<commit_before>/**
 * @file llhints.cpp
 * @brief Hint popups for displaying context sensitive help in a UI overlay
 *
 * $LicenseInfo:firstyear=2000&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" // must be first include

#include "llhints.h"

#include "llbutton.h"
#include "lltextbox.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "llsdparam.h"

class LLHintPopup : public LLPanel
{
public:

	typedef enum e_popup_direction
	{
		LEFT,
		TOP,
		RIGHT,
		BOTTOM,
		TOP_RIGHT
	} EPopupDirection;

	struct PopupDirections : public LLInitParam::TypeValuesHelper<LLHintPopup::EPopupDirection, PopupDirections>
	{
		static void declareValues()
		{
			declare("left", LLHintPopup::LEFT);
			declare("right", LLHintPopup::RIGHT);
			declare("top", LLHintPopup::TOP);
			declare("bottom", LLHintPopup::BOTTOM);
			declare("top_right", LLHintPopup::TOP_RIGHT);
		}
	};

	struct TargetParams : public LLInitParam::Block<TargetParams>
	{
		Mandatory<std::string>	target;
		Mandatory<EPopupDirection, PopupDirections> direction;

		TargetParams()
		:	target("target"),
			direction("direction")
		{}
	};

	struct Params : public LLInitParam::Block<Params, LLPanel::Params>
	{
		Mandatory<LLNotificationPtr>	notification;
		Optional<TargetParams>			target_params;
		Optional<S32>					distance;
		Optional<LLUIImage*>			left_arrow,
										up_arrow,
										right_arrow,
										down_arrow,
										lower_left_arrow;

		Optional<S32>					left_arrow_offset,
										up_arrow_offset,
										right_arrow_offset,
										down_arrow_offset;
		Optional<F32>					fade_in_time,
										fade_out_time;

		Params()
		:	distance("distance"),
			left_arrow("left_arrow"),
			up_arrow("up_arrow"),
			right_arrow("right_arrow"),
			down_arrow("down_arrow"),
			lower_left_arrow("lower_left_arrow"),
			left_arrow_offset("left_arrow_offset"),
			up_arrow_offset("up_arrow_offset"),
			right_arrow_offset("right_arrow_offset"),
			down_arrow_offset("down_arrow_offset"),
			fade_in_time("fade_in_time"),
			fade_out_time("fade_out_time")
		{}
	};

	LLHintPopup(const Params&);

	/*virtual*/ BOOL postBuild();

	void onClickClose() { hide(); LLNotifications::instance().cancel(mNotification); }
	void draw();
	void hide() { if(!mHidden) {mHidden = true; mFadeTimer.reset();} }

private:
	LLNotificationPtr	mNotification;
	std::string			mTarget;
	EPopupDirection		mDirection;
	S32					mDistance;
	LLUIImagePtr		mArrowLeft,
						mArrowUp,
						mArrowRight,
						mArrowDown,
						mArrowDownAndLeft;
	S32					mArrowLeftOffset,
						mArrowUpOffset,
						mArrowRightOffset,
						mArrowDownOffset;
	LLFrameTimer		mFadeTimer;
	F32					mFadeInTime,
						mFadeOutTime;
	bool				mHidden;
};

static LLDefaultChildRegistry::Register<LLHintPopup> r("hint_popup");

LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
:	mNotification(p.notification),
	mDirection(TOP),
	mDistance(p.distance),
	mArrowLeft(p.left_arrow),
	mArrowUp(p.up_arrow),
	mArrowRight(p.right_arrow),
	mArrowDown(p.down_arrow),
	mArrowDownAndLeft(p.lower_left_arrow),
	mArrowLeftOffset(p.left_arrow_offset),
	mArrowUpOffset(p.up_arrow_offset),
	mArrowRightOffset(p.right_arrow_offset),
	mArrowDownOffset(p.down_arrow_offset),
	mHidden(false),
	mFadeInTime(p.fade_in_time),
	mFadeOutTime(p.fade_out_time),
	LLPanel(p)
{
	if (p.target_params.isProvided())
	{
		mDirection = p.target_params.direction;
		mTarget = p.target_params.target;
	}
	buildFromFile( "panel_hint.xml", NULL, p);
}

BOOL LLHintPopup::postBuild()
{
	LLTextBox& hint_text = getChildRef<LLTextBox>("hint_text");
	hint_text.setText(mNotification->getMessage());

	getChild<LLButton>("close")->setClickedCallback(boost::bind(&LLHintPopup::onClickClose, this));
	getChild<LLTextBox>("hint_title")->setText(mNotification->getLabel());

	LLRect text_bounds = hint_text.getTextBoundingRect();
	S32 delta_height = text_bounds.getHeight() - hint_text.getRect().getHeight();
	reshape(getRect().getWidth(), getRect().getHeight() + delta_height);
	return TRUE;
}

void LLHintPopup::draw()
{
	F32 alpha = 1.f;
	if (mHidden)
	{
		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeOutTime, 1.f, 0.f);
		if (alpha == 0.f)
		{
			die();
			return;
		}
	}
	else
	{
		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeInTime, 0.f, 1.f);
	}

	{	LLViewDrawContext context(alpha);

		if (mTarget.empty())
		{
			// just draw contents, no arrow, in default position
			LLPanel::draw();
		}
		else
		{
			LLView* targetp = LLHints::getHintTarget(mTarget).get();
			if (!targetp)
			{
				// target widget is no longer valid, go away
				die();
			}
			else if (!targetp->isInVisibleChain())
			{
				// if target is invisible, don't draw, but keep alive in case widget comes back
				// but do make it so that it allows mouse events to pass through
				setEnabled(false);
				setMouseOpaque(false);
			}
			else
			{
				// revert back enabled and mouse opaque state in case we disabled it before
				setEnabled(true);
				setMouseOpaque(true);

				LLRect target_rect;
				targetp->localRectToOtherView(targetp->getLocalRect(), &target_rect, getParent());

				LLRect my_local_rect = getLocalRect();
				LLRect my_rect;
				LLRect arrow_rect;
				LLUIImagePtr arrow_imagep;

				switch(mDirection)
				{
				case LEFT:
					my_rect.setCenterAndSize(	target_rect.mLeft - (my_local_rect.getWidth() / 2 + mDistance),
												target_rect.getCenterY(),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowRight)
					{
						arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 + mArrowRightOffset,
													my_local_rect.getCenterY(),
													mArrowRight->getWidth(),
													mArrowRight->getHeight());
						arrow_imagep = mArrowRight;
					}
					break;
				case TOP:
					my_rect.setCenterAndSize(	target_rect.getCenterX(),
												target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowDown)
					{
						arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
													my_local_rect.mBottom - mArrowDown->getHeight() / 2 + mArrowDownOffset,
													mArrowDown->getWidth(),
													mArrowDown->getHeight());
						arrow_imagep = mArrowDown;
					}
					break;
				case RIGHT:
					my_rect.setCenterAndSize(	target_rect.mRight + (my_local_rect.getWidth() / 2 + mDistance),
												target_rect.getCenterY(),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowLeft)
					{
						arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + mArrowLeftOffset,
													my_local_rect.getCenterY(),
													mArrowLeft->getWidth(),
													mArrowLeft->getHeight());
						arrow_imagep = mArrowLeft;
					}
					break;
				case BOTTOM:
					my_rect.setCenterAndSize(	target_rect.getCenterX(),
												target_rect.mBottom - (my_local_rect.getHeight() / 2 + mDistance),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowUp)
					{
						arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
													my_local_rect.mTop + mArrowUp->getHeight() / 2 + mArrowUpOffset,
													mArrowUp->getWidth(),
													mArrowUp->getHeight());
						arrow_imagep = mArrowUp;
					}
					break;
				case TOP_RIGHT:
					my_rect.setCenterAndSize(	target_rect.mRight + (my_local_rect.getWidth() / 2),
												target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowDownAndLeft)
					{
						arrow_rect.setCenterAndSize(my_local_rect.mLeft + mArrowDownAndLeft->getWidth() / 2 + mArrowLeftOffset,
													my_local_rect.mBottom - mArrowDownAndLeft->getHeight() / 2 + mArrowDownOffset,
													mArrowDownAndLeft->getWidth(),
													mArrowDownAndLeft->getHeight());
						arrow_imagep = mArrowDownAndLeft;
					}
				}
				setShape(my_rect);
				LLPanel::draw();

				if (arrow_imagep) arrow_imagep->draw(arrow_rect, LLColor4(1.f, 1.f, 1.f, alpha));
			}
		}
	}
}

LLRegistry<std::string, LLHandle<LLView> > LLHints::sTargetRegistry;
std::map<LLNotificationPtr, class LLHintPopup*> LLHints::sHints;

//static
void LLHints::show(LLNotificationPtr hint)
{
	LLHintPopup::Params p(LLUICtrlFactory::getDefaultParams<LLHintPopup>());

	LLParamSDParser parser;
	parser.readSD(hint->getPayload(), p, true);
	p.notification = hint;

	if (p.validateBlock())
	{
		LLHintPopup* popup = new LLHintPopup(p);

		sHints[hint] = popup;

		LLView* hint_holder = gViewerWindow->getHintHolder();
		if (hint_holder)
		{
			hint_holder->addChild(popup);
			popup->centerWithin(hint_holder->getLocalRect());
		}
	}
}

//static
void LLHints::hide(LLNotificationPtr hint)
{
	hint_map_t::iterator found_it = sHints.find(hint);
	if (found_it != sHints.end())
	{
		found_it->second->hide();
		sHints.erase(found_it);
	}
}

//static
void LLHints::registerHintTarget(const std::string& name, LLHandle<LLView> target)
{
	sTargetRegistry.defaultRegistrar().replace(name, target);
}

//static
LLHandle<LLView> LLHints::getHintTarget(const std::string& name)
{
	LLHandle<LLView>* handlep = sTargetRegistry.getValue(name);
	if (handlep)
	{
		return *handlep;
	}
	else
	{
		return LLHandle<LLView>();
	}
}

//static
void LLHints::initClass()
{
	sRegister.reference();

	LLControlVariablePtr control = gSavedSettings.getControl("EnableUIHints");
	control->getSignal()->connect(boost::bind(&showHints, _2));
	gViewerWindow->getHintHolder()->setVisible(control->getValue().asBoolean());

}

//staic
void LLHints::showHints(const LLSD& show)
{
	bool visible = show.asBoolean();
	gViewerWindow->getHintHolder()->setVisible(visible);
}
<commit_msg>VWR-23444 FIXED Double clicking x on UI hint crashes Skylight Viewer<commit_after>/**
 * @file llhints.cpp
 * @brief Hint popups for displaying context sensitive help in a UI overlay
 *
 * $LicenseInfo:firstyear=2000&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" // must be first include

#include "llhints.h"

#include "llbutton.h"
#include "lltextbox.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "llsdparam.h"

class LLHintPopup : public LLPanel
{
public:

	typedef enum e_popup_direction
	{
		LEFT,
		TOP,
		RIGHT,
		BOTTOM,
		TOP_RIGHT
	} EPopupDirection;

	struct PopupDirections : public LLInitParam::TypeValuesHelper<LLHintPopup::EPopupDirection, PopupDirections>
	{
		static void declareValues()
		{
			declare("left", LLHintPopup::LEFT);
			declare("right", LLHintPopup::RIGHT);
			declare("top", LLHintPopup::TOP);
			declare("bottom", LLHintPopup::BOTTOM);
			declare("top_right", LLHintPopup::TOP_RIGHT);
		}
	};

	struct TargetParams : public LLInitParam::Block<TargetParams>
	{
		Mandatory<std::string>	target;
		Mandatory<EPopupDirection, PopupDirections> direction;

		TargetParams()
		:	target("target"),
			direction("direction")
		{}
	};

	struct Params : public LLInitParam::Block<Params, LLPanel::Params>
	{
		Mandatory<LLNotificationPtr>	notification;
		Optional<TargetParams>			target_params;
		Optional<S32>					distance;
		Optional<LLUIImage*>			left_arrow,
										up_arrow,
										right_arrow,
										down_arrow,
										lower_left_arrow;

		Optional<S32>					left_arrow_offset,
										up_arrow_offset,
										right_arrow_offset,
										down_arrow_offset;
		Optional<F32>					fade_in_time,
										fade_out_time;

		Params()
		:	distance("distance"),
			left_arrow("left_arrow"),
			up_arrow("up_arrow"),
			right_arrow("right_arrow"),
			down_arrow("down_arrow"),
			lower_left_arrow("lower_left_arrow"),
			left_arrow_offset("left_arrow_offset"),
			up_arrow_offset("up_arrow_offset"),
			right_arrow_offset("right_arrow_offset"),
			down_arrow_offset("down_arrow_offset"),
			fade_in_time("fade_in_time"),
			fade_out_time("fade_out_time")
		{}
	};

	LLHintPopup(const Params&);

	/*virtual*/ BOOL postBuild();

	void onClickClose()
	{
		if (!mHidden)
		{
			hide();
			LLNotifications::instance().cancel(mNotification);
		}
	}
	void draw();
	void hide() { if(!mHidden) {mHidden = true; mFadeTimer.reset();} }

private:
	LLNotificationPtr	mNotification;
	std::string			mTarget;
	EPopupDirection		mDirection;
	S32					mDistance;
	LLUIImagePtr		mArrowLeft,
						mArrowUp,
						mArrowRight,
						mArrowDown,
						mArrowDownAndLeft;
	S32					mArrowLeftOffset,
						mArrowUpOffset,
						mArrowRightOffset,
						mArrowDownOffset;
	LLFrameTimer		mFadeTimer;
	F32					mFadeInTime,
						mFadeOutTime;
	bool				mHidden;
};

static LLDefaultChildRegistry::Register<LLHintPopup> r("hint_popup");

LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
:	mNotification(p.notification),
	mDirection(TOP),
	mDistance(p.distance),
	mArrowLeft(p.left_arrow),
	mArrowUp(p.up_arrow),
	mArrowRight(p.right_arrow),
	mArrowDown(p.down_arrow),
	mArrowDownAndLeft(p.lower_left_arrow),
	mArrowLeftOffset(p.left_arrow_offset),
	mArrowUpOffset(p.up_arrow_offset),
	mArrowRightOffset(p.right_arrow_offset),
	mArrowDownOffset(p.down_arrow_offset),
	mHidden(false),
	mFadeInTime(p.fade_in_time),
	mFadeOutTime(p.fade_out_time),
	LLPanel(p)
{
	if (p.target_params.isProvided())
	{
		mDirection = p.target_params.direction;
		mTarget = p.target_params.target;
	}
	buildFromFile( "panel_hint.xml", NULL, p);
}

BOOL LLHintPopup::postBuild()
{
	LLTextBox& hint_text = getChildRef<LLTextBox>("hint_text");
	hint_text.setText(mNotification->getMessage());

	getChild<LLButton>("close")->setClickedCallback(boost::bind(&LLHintPopup::onClickClose, this));
	getChild<LLTextBox>("hint_title")->setText(mNotification->getLabel());

	LLRect text_bounds = hint_text.getTextBoundingRect();
	S32 delta_height = text_bounds.getHeight() - hint_text.getRect().getHeight();
	reshape(getRect().getWidth(), getRect().getHeight() + delta_height);
	return TRUE;
}

void LLHintPopup::draw()
{
	F32 alpha = 1.f;
	if (mHidden)
	{
		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeOutTime, 1.f, 0.f);
		if (alpha == 0.f)
		{
			die();
			return;
		}
	}
	else
	{
		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeInTime, 0.f, 1.f);
	}

	{	LLViewDrawContext context(alpha);

		if (mTarget.empty())
		{
			// just draw contents, no arrow, in default position
			LLPanel::draw();
		}
		else
		{
			LLView* targetp = LLHints::getHintTarget(mTarget).get();
			if (!targetp)
			{
				// target widget is no longer valid, go away
				die();
			}
			else if (!targetp->isInVisibleChain())
			{
				// if target is invisible, don't draw, but keep alive in case widget comes back
				// but do make it so that it allows mouse events to pass through
				setEnabled(false);
				setMouseOpaque(false);
			}
			else
			{
				// revert back enabled and mouse opaque state in case we disabled it before
				setEnabled(true);
				setMouseOpaque(true);

				LLRect target_rect;
				targetp->localRectToOtherView(targetp->getLocalRect(), &target_rect, getParent());

				LLRect my_local_rect = getLocalRect();
				LLRect my_rect;
				LLRect arrow_rect;
				LLUIImagePtr arrow_imagep;

				switch(mDirection)
				{
				case LEFT:
					my_rect.setCenterAndSize(	target_rect.mLeft - (my_local_rect.getWidth() / 2 + mDistance),
												target_rect.getCenterY(),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowRight)
					{
						arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 + mArrowRightOffset,
													my_local_rect.getCenterY(),
													mArrowRight->getWidth(),
													mArrowRight->getHeight());
						arrow_imagep = mArrowRight;
					}
					break;
				case TOP:
					my_rect.setCenterAndSize(	target_rect.getCenterX(),
												target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowDown)
					{
						arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
													my_local_rect.mBottom - mArrowDown->getHeight() / 2 + mArrowDownOffset,
													mArrowDown->getWidth(),
													mArrowDown->getHeight());
						arrow_imagep = mArrowDown;
					}
					break;
				case RIGHT:
					my_rect.setCenterAndSize(	target_rect.mRight + (my_local_rect.getWidth() / 2 + mDistance),
												target_rect.getCenterY(),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowLeft)
					{
						arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + mArrowLeftOffset,
													my_local_rect.getCenterY(),
													mArrowLeft->getWidth(),
													mArrowLeft->getHeight());
						arrow_imagep = mArrowLeft;
					}
					break;
				case BOTTOM:
					my_rect.setCenterAndSize(	target_rect.getCenterX(),
												target_rect.mBottom - (my_local_rect.getHeight() / 2 + mDistance),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowUp)
					{
						arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
													my_local_rect.mTop + mArrowUp->getHeight() / 2 + mArrowUpOffset,
													mArrowUp->getWidth(),
													mArrowUp->getHeight());
						arrow_imagep = mArrowUp;
					}
					break;
				case TOP_RIGHT:
					my_rect.setCenterAndSize(	target_rect.mRight + (my_local_rect.getWidth() / 2),
												target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance),
												my_local_rect.getWidth(),
												my_local_rect.getHeight());
					if (mArrowDownAndLeft)
					{
						arrow_rect.setCenterAndSize(my_local_rect.mLeft + mArrowDownAndLeft->getWidth() / 2 + mArrowLeftOffset,
													my_local_rect.mBottom - mArrowDownAndLeft->getHeight() / 2 + mArrowDownOffset,
													mArrowDownAndLeft->getWidth(),
													mArrowDownAndLeft->getHeight());
						arrow_imagep = mArrowDownAndLeft;
					}
				}
				setShape(my_rect);
				LLPanel::draw();

				if (arrow_imagep) arrow_imagep->draw(arrow_rect, LLColor4(1.f, 1.f, 1.f, alpha));
			}
		}
	}
}

LLRegistry<std::string, LLHandle<LLView> > LLHints::sTargetRegistry;
std::map<LLNotificationPtr, class LLHintPopup*> LLHints::sHints;

//static
void LLHints::show(LLNotificationPtr hint)
{
	LLHintPopup::Params p(LLUICtrlFactory::getDefaultParams<LLHintPopup>());

	LLParamSDParser parser;
	parser.readSD(hint->getPayload(), p, true);
	p.notification = hint;

	if (p.validateBlock())
	{
		LLHintPopup* popup = new LLHintPopup(p);

		sHints[hint] = popup;

		LLView* hint_holder = gViewerWindow->getHintHolder();
		if (hint_holder)
		{
			hint_holder->addChild(popup);
			popup->centerWithin(hint_holder->getLocalRect());
		}
	}
}

//static
void LLHints::hide(LLNotificationPtr hint)
{
	hint_map_t::iterator found_it = sHints.find(hint);
	if (found_it != sHints.end())
	{
		found_it->second->hide();
		sHints.erase(found_it);
	}
}

//static
void LLHints::registerHintTarget(const std::string& name, LLHandle<LLView> target)
{
	sTargetRegistry.defaultRegistrar().replace(name, target);
}

//static
LLHandle<LLView> LLHints::getHintTarget(const std::string& name)
{
	LLHandle<LLView>* handlep = sTargetRegistry.getValue(name);
	if (handlep)
	{
		return *handlep;
	}
	else
	{
		return LLHandle<LLView>();
	}
}

//static
void LLHints::initClass()
{
	sRegister.reference();

	LLControlVariablePtr control = gSavedSettings.getControl("EnableUIHints");
	control->getSignal()->connect(boost::bind(&showHints, _2));
	gViewerWindow->getHintHolder()->setVisible(control->getValue().asBoolean());

}

//staic
void LLHints::showHints(const LLSD& show)
{
	bool visible = show.asBoolean();
	gViewerWindow->getHintHolder()->setVisible(visible);
}
<|endoftext|>


<commit_before>#include "InterpreterTest.h"

#include "benchmark/benchmark.h"

BENCHMARK_CAPTURE(TestTutorial, Test_nopch_minuit2, "tutorials/", "fit/minuit2FitBench.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_minuit2Gaus, "tutorials/", "fit/minuit2GausFit.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_quadp, "tutorials/", "quadp/portfolio.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_foam, "tutorials/", "foam/foam_demo.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_fftw, "tutorials/", "fft/FFT.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mlp_higgs, "tutorials/", "mlp/mlpHiggs.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mlp_regression, "tutorials/", "mlp/mlpRegression.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mlp_higgs, "tutorials/", "mlp/mlpHiggs.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mlp_regression, "tutorials/", "mlp/mlpRegression.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_assembly, "tutorials/", "geom/assembly.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_na49, "tutorials/", "geom/na49.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_geamAlice, "tutorials/", "geom/geamAlice.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_geamAtlas, "tutorials/", "geom/geamAtlas.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mp3player, "tutorials/", "geom/mp3player.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_geamD0, "tutorials/", "geom/geamD0.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_radionucl, "tutorials/", "geom/RadioNuclides.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_rootgeom, "tutorials/", "geom/rootgeom.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_geodemo, "tutorials/", "geom/geodemo.C")->Unit(benchmark::kMicrosecond);

BENCHMARK_MAIN();
<commit_msg>Fixing typos in names of geometry tutorials<commit_after>#include "InterpreterTest.h"

#include "benchmark/benchmark.h"

BENCHMARK_CAPTURE(TestTutorial, Test_nopch_minuit2, "tutorials/", "fit/minuit2FitBench.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_minuit2Gaus, "tutorials/", "fit/minuit2GausFit.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_quadp, "tutorials/", "quadp/portfolio.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_foam, "tutorials/", "foam/foam_demo.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_fftw, "tutorials/", "fft/FFT.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mlp_higgs, "tutorials/", "mlp/mlpHiggs.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mlp_regression, "tutorials/", "mlp/mlpRegression.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mlp_higgs, "tutorials/", "mlp/mlpHiggs.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mlp_regression, "tutorials/", "mlp/mlpRegression.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_assembly, "tutorials/", "geom/assembly.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_na49, "tutorials/", "geom/na49.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_geomAlice, "tutorials/", "geom/geomAlice.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_geomAtlas, "tutorials/", "geom/geomAtlas.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_mp3player, "tutorials/", "geom/mp3player.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_geamD0, "tutorials/", "geom/geomD0.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_radionucl, "tutorials/", "geom/RadioNuclides.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_rootgeom, "tutorials/", "geom/rootgeom.C")->Unit(benchmark::kMicrosecond);
BENCHMARK_CAPTURE(TestTutorial, Test_nopch_geodemo, "tutorials/", "geom/geodemo.C")->Unit(benchmark::kMicrosecond);

BENCHMARK_MAIN();
<|endoftext|>


<commit_before>// This file is part of libAthena.
//
// libAthena is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libAthena 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libAthena.  If not, see <http://www.gnu.org/licenses/>

#include "Athena/ZQuestFileReader.hpp"
#include "Athena/ZQuestFile.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/Compression.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/Checksums.hpp"
#include "Athena/Utility.hpp"
#include <iostream>
#include <iomanip>

namespace Athena
{
namespace io
{

ZQuestFileReader::ZQuestFileReader(Uint8 *data, Uint64 length)
    : base(data, length)
{
}

ZQuestFileReader::ZQuestFileReader(const std::string &filename)
    : base(filename)
{
}

ZQuestFile *ZQuestFileReader::read()
{
    Uint32 magic, version, compressedLen, uncompressedLen;
    ZQuestFile::Game game = ZQuestFile::NoGame;
    std::string gameString;
    Uint16 BOM;
    Uint32 checksum;
    Uint8* data;

    magic = base::readUint32();

    if ((magic & 0x00FFFFFF) != (ZQuestFile::Magic & 0x00FFFFFF))
        THROW_INVALID_DATA_EXCEPTION("Not a valid ZQuest file");

    version = base::readUint32();

    if (version > ZQuestFile::Version)
        THROW_INVALID_DATA_EXCEPTION("Unsupported ZQuest version");

    compressedLen = base::readUint32();
    uncompressedLen = base::readUint32();

    if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
    {
        gameString = ((const char*)base::readBytes(0x0A), 0x0A);
        for (size_t i = 0; i <  ZQuestFile::gameStringList().size(); i++)
        {
            if (!ZQuestFile::gameStringList().at(i).substr(0, 0x0A).compare(gameString))
            {
                gameString = ZQuestFile::gameStringList().at(i);
                break;
            }

        }
        BOM = base::readUint16();
        checksum = base::readUint32();
    }
    else
    {
        game = (ZQuestFile::Game)base::readUint32();
        BOM = base::readUint16();
        std::cerr << "Test" << std::endl;
        base::seek(0x0A);
    }

    data = (Uint8*)base::readBytes(compressedLen); // compressedLen is always the total file size

    if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
    {
        if (checksum != Athena::Checksums::crc32(data, compressedLen))
        {
            delete[] data;
            THROW_INVALID_DATA_EXCEPTION("Checksum mismatch, data corrupt");
        }
    }
    else
    {
        std::clog << "ZQuest version 0x" << std::uppercase << std::setw(8) << std::setfill('0') << std::hex << Athena::utility::swapU32(version);
        std::clog << " has no checksum field" << std::endl;
    }

    if (compressedLen != uncompressedLen)
    {
        Uint8* dst = new Uint8[uncompressedLen];
        Uint32 dstLen = io::Compression::decompressZlib(data, compressedLen, dst, uncompressedLen);

        if (dstLen != uncompressedLen)
        {
            delete[] dst;
            delete[] data;
            // TODO: Make proper exception
            THROW_INVALID_DATA_EXCEPTION("Error decompressing data");
        }

        delete[] data;
        data = dst;
    }

    return new ZQuestFile(game, BOM == 0xFEFF ? Endian::BigEndian : Endian::LittleEndian, data, uncompressedLen, gameString);
}

} // io
} // zelda
<commit_msg>* Fix but in ZQuest, where gameString was being improperly assigned<commit_after>// This file is part of libAthena.
//
// libAthena is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libAthena 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libAthena.  If not, see <http://www.gnu.org/licenses/>

#include "Athena/ZQuestFileReader.hpp"
#include "Athena/ZQuestFile.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/Compression.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/Checksums.hpp"
#include "Athena/Utility.hpp"
#include <iostream>
#include <iomanip>

namespace Athena
{
namespace io
{

ZQuestFileReader::ZQuestFileReader(Uint8 *data, Uint64 length)
    : base(data, length)
{
}

ZQuestFileReader::ZQuestFileReader(const std::string &filename)
    : base(filename)
{
}

ZQuestFile *ZQuestFileReader::read()
{
    Uint32 magic, version, compressedLen, uncompressedLen;
    ZQuestFile::Game game = ZQuestFile::NoGame;
    std::string gameString;
    Uint16 BOM;
    Uint32 checksum;
    Uint8* data;

    magic = base::readUint32();

    if ((magic & 0x00FFFFFF) != (ZQuestFile::Magic & 0x00FFFFFF))
        THROW_INVALID_DATA_EXCEPTION("Not a valid ZQuest file");

    version = base::readUint32();

    if (version > ZQuestFile::Version)
        THROW_INVALID_DATA_EXCEPTION("Unsupported ZQuest version");

    compressedLen = base::readUint32();
    uncompressedLen = base::readUint32();

    if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
    {
        gameString = std::string((const char*)base::readBytes(0x0A), 0x0A);
        for (size_t i = 0; i <  ZQuestFile::gameStringList().size(); i++)
        {
            if (!ZQuestFile::gameStringList().at(i).substr(0, 0x0A).compare(gameString))
            {
                gameString = ZQuestFile::gameStringList().at(i);
                game = (ZQuestFile::Game)i;
                break;
            }
        }
        BOM = base::readUint16();
        checksum = base::readUint32();
    }
    else
    {
        game = (ZQuestFile::Game)base::readUint32();
        BOM = base::readUint16();
        std::cerr << "Test" << std::endl;
        base::seek(0x0A);
    }

    data = (Uint8*)base::readBytes(compressedLen); // compressedLen is always the total file size

    if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
    {
        if (checksum != Athena::Checksums::crc32(data, compressedLen))
        {
            delete[] data;
            THROW_INVALID_DATA_EXCEPTION("Checksum mismatch, data corrupt");
        }
    }
    else
    {
        std::clog << "ZQuest version 0x" << std::uppercase << std::setw(8) << std::setfill('0') << std::hex << Athena::utility::swapU32(version);
        std::clog << " has no checksum field" << std::endl;
    }

    if (compressedLen != uncompressedLen)
    {
        Uint8* dst = new Uint8[uncompressedLen];
        Uint32 dstLen = io::Compression::decompressZlib(data, compressedLen, dst, uncompressedLen);

        if (dstLen != uncompressedLen)
        {
            delete[] dst;
            delete[] data;
            // TODO: Make proper exception
            THROW_INVALID_DATA_EXCEPTION("Error decompressing data");
        }

        delete[] data;
        data = dst;
    }

    return new ZQuestFile(game, BOM == 0xFEFF ? Endian::BigEndian : Endian::LittleEndian, data, uncompressedLen, gameString);
}

} // io
} // zelda
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/cache/p9_hcd_cache_stopclocks.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file  p9_hcd_cache_stopclocks.C
/// @brief Quad Clock Stop
///
/// Procedure Summary:

// *HWP HWP Owner          : David Du       <daviddu@us.ibm.com>
// *HWP Backup HWP Owner   : Greg Still     <stillgs@us.ibm.com>
// *HWP FW Owner           : Sangeetha T S  <sangeet2@in.ibm.com>
// *HWP Team               : PM
// *HWP Consumed by        : HB:PERV
// *HWP Level              : 2

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------

#include <p9_misc_scom_addresses.H>
#include <p9_quad_scom_addresses.H>
#include <p9_hcd_common.H>
#include <p9_common_clk_ctrl_state.H>
#include "p9_hcd_l2_stopclocks.H"
#include "p9_hcd_cache_stopclocks.H"

//------------------------------------------------------------------------------
// Constant Definitions
//------------------------------------------------------------------------------

enum P9_HCD_CACHE_STOPCLOCKS_CONSTANTS
{
    CACHE_CLK_STOP_POLLING_HW_NS_DELAY     = 10000,
    CACHE_CLK_STOP_POLLING_SIM_CYCLE_DELAY = 320000
};

//------------------------------------------------------------------------------
// Procedure: Quad Clock Stop
//------------------------------------------------------------------------------

fapi2::ReturnCode
p9_hcd_cache_stopclocks(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
    const p9hcd::P9_HCD_CLK_CTRL_CONSTANTS      i_select_regions,
    const p9hcd::P9_HCD_EX_CTRL_CONSTANTS       i_select_ex)
{
    FAPI_INF(">>p9_hcd_cache_stopclocks: regions[%016llx] ex[%d]",
             i_select_regions, i_select_ex);
    fapi2::ReturnCode                              l_rc;
    fapi2::buffer<uint64_t>                        l_data64;
    fapi2::buffer<uint64_t>                        l_temp64;
    uint64_t                                       l_l3mask_pscom = 0;
    uint32_t                                       l_loops1ms;
    uint8_t                                        l_attr_chip_unit_pos = 0;
    uint8_t                                        l_attr_vdm_enable;
    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> l_sys;
    auto l_perv = i_target.getParent<fapi2::TARGET_TYPE_PERV>();
    auto l_chip = i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDM_ENABLE,    l_sys,
                           l_attr_vdm_enable));
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_perv,
                           l_attr_chip_unit_pos));
//  l_attr_chip_unit_pos = l_attr_chip_unit_pos - p9hcd::PERV_TO_QUAD_POS_OFFSET;
    l_attr_chip_unit_pos = l_attr_chip_unit_pos - 0x10;

    if (i_select_regions & p9hcd::CLK_REGION_EX0_L3)
    {
        l_l3mask_pscom |= (BIT64(4) | BIT64(6) | BIT64(8));
    }

    if (i_select_regions & p9hcd::CLK_REGION_EX1_L3)
    {
        l_l3mask_pscom |= (BIT64(5) | BIT64(7) | BIT64(9));
    }

    // -----------------------------
    // Prepare to stop cache clocks
    // -----------------------------

    FAPI_DBG("Check PM_RESET_STATE_INDICATOR via GPMMR[15]");
    FAPI_TRY(getScom(i_target, EQ_PPM_GPMMR_SCOM, l_data64));

    if (!l_data64.getBit<15>())
    {
        FAPI_DBG("Gracefully turn off power management, if fail, continue anyways");
        /// @todo RTC158181 suspend_pm()
    }

    FAPI_DBG("Check cache clock controller status");
    l_rc = p9_common_clk_ctrl_state<fapi2::TARGET_TYPE_EQ>(i_target);

    if (l_rc)
    {
        FAPI_INF("Clock controller of this cache chiplet is inaccessible, return");
        goto fapi_try_exit;
    }

    FAPI_DBG("Check PERV clock status for access to CME via CLOCK_STAT[4]");
    FAPI_TRY(getScom(i_target, EQ_CLOCK_STAT_SL, l_data64));

    FAPI_DBG("Check PERV fence status for access to CME via CPLT_CTRL1[4]");
    FAPI_TRY(getScom(i_target, EQ_CPLT_CTRL1, l_temp64));

    if (l_data64.getBit<4>() == 0 && l_temp64.getBit<4>() == 0)
    {
        /// @todo RTC158181 disable l2 snoop? disable lco? assert refresh quiesce?
        FAPI_DBG("Assert L3 pscom masks via RING_FENCE_MASK_LATCH_REG[4-9]");
        FAPI_TRY(putScom(i_target, EQ_RING_FENCE_MASK_LATCH_REG, l_l3mask_pscom));
    }

    FAPI_DBG("Assert chiplet fence via NET_CTRL0[18]");
    FAPI_TRY(putScom(i_target, EQ_NET_CTRL0_WOR, MASK_SET(18)));

    // -------------------------------
    // Stop L2 clocks
    // -------------------------------

    if (i_select_ex)
        FAPI_EXEC_HWP(fapi2::current_err,
                      p9_hcd_l2_stopclocks,
                      i_target, i_select_ex);

    // -------------------------------
    // Stop cache clocks
    // -------------------------------

    FAPI_DBG("Clear all SCAN_REGION_TYPE bits");
    FAPI_TRY(putScom(i_target, EQ_SCAN_REGION_TYPE, MASK_ZERO));

    FAPI_DBG("Stop cache clocks via CLK_REGION");
    l_data64 = (p9hcd::CLK_STOP_CMD  |
                i_select_regions     |
                p9hcd::CLK_THOLD_ALL);
    FAPI_TRY(putScom(i_target, EQ_CLK_REGION, l_data64));

    FAPI_DBG("Poll for cache clocks stopped via CPLT_STAT0[8]");
    l_loops1ms = 1E6 / CACHE_CLK_STOP_POLLING_HW_NS_DELAY;

    do
    {
        fapi2::delay(CACHE_CLK_STOP_POLLING_HW_NS_DELAY,
                     CACHE_CLK_STOP_POLLING_SIM_CYCLE_DELAY);

        FAPI_TRY(getScom(i_target, EQ_CPLT_STAT0, l_data64));
    }
    while((l_data64.getBit<8>() != 1) && ((--l_loops1ms) != 0));

    FAPI_ASSERT((l_loops1ms != 0),
                fapi2::PMPROC_CACHECLKSTOP_TIMEOUT().set_EQCPLTSTAT(l_data64),
                "Cache Clock Stop Timeout");

    FAPI_DBG("Check cache clocks stopped");
    FAPI_TRY(getScom(i_target, EQ_CLOCK_STAT_SL, l_data64));

    FAPI_ASSERT((((~l_data64) & i_select_regions) == 0),
                fapi2::PMPROC_CACHECLKSTOP_FAILED().set_EQCLKSTAT(l_data64),
                "Cache Clock Stop Failed");
    FAPI_DBG("Cache clocks stopped now");

    // -------------------------------
    // Fence up
    // -------------------------------

    FAPI_DBG("Assert vital fence via CPLT_CTRL1[3]");
    FAPI_TRY(putScom(i_target, EQ_CPLT_CTRL1_OR, MASK_SET(3)));

    FAPI_DBG("Assert regional fences via CPLT_CTRL1[4-14]");
    FAPI_TRY(putScom(i_target, EQ_CPLT_CTRL1_OR, i_select_regions));

    // -------------------------------
    // Disable VDM
    // -------------------------------

    if (l_attr_vdm_enable == fapi2::ENUM_ATTR_VDM_ENABLE_ON)
    {
        FAPI_DBG("Drop vdm enable via QPPM_VDMCR[0]");
        FAPI_TRY(putScom(i_target, EQ_PPM_VDMCR_CLEAR, MASK_SET(0)));
    }

    // -------------------------------
    // Shutdown edram
    // -------------------------------
    // QCCR[0/4] EDRAM_ENABLE_DC
    // QCCR[1/5] EDRAM_VWL_ENABLE_DC
    // QCCR[2/6] L3_EX0/1_EDRAM_VROW_VBLH_ENABLE_DC
    // QCCR[3/7] EDRAM_VPP_ENABLE_DC

    if (i_select_regions & p9hcd::CLK_REGION_EX0_REFR)
    {
        FAPI_DBG("Sequence EX0 EDRAM disables via QPPM_QCCR[0-3]");
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(3)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(2)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(1)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(0)));
    }

    if (i_select_regions & p9hcd::CLK_REGION_EX1_REFR)
    {
        FAPI_DBG("Sequence EX1 EDRAM disables via QPPM_QCCR[4-7]");
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(7)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(6)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(5)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(4)));
    }

    // -------------------------------
    // Update QSSR and STOP history
    // -------------------------------

    FAPI_DBG("Set cache as stopped in QSSR");
    FAPI_TRY(putScom(l_chip, PU_OCB_OCI_QSSR_OR,
                     BIT64(l_attr_chip_unit_pos + 14)));

    FAPI_DBG("Set cache as stopped in STOP history register");
    FAPI_TRY(putScom(i_target, EQ_PPM_SSHSRC, BIT64(0)));

fapi_try_exit:

    FAPI_INF("<<p9_hcd_cache_stopclocks");
    return fapi2::current_err;
}
<commit_msg>PB Purge Scoms if PBIEQ clock domain is being stopped<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/cache/p9_hcd_cache_stopclocks.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file  p9_hcd_cache_stopclocks.C
/// @brief Quad Clock Stop
///
/// Procedure Summary:

// *HWP HWP Owner          : David Du       <daviddu@us.ibm.com>
// *HWP Backup HWP Owner   : Greg Still     <stillgs@us.ibm.com>
// *HWP FW Owner           : Sangeetha T S  <sangeet2@in.ibm.com>
// *HWP Team               : PM
// *HWP Consumed by        : HB:PERV
// *HWP Level              : 2

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------

#include <p9_misc_scom_addresses.H>
#include <p9_quad_scom_addresses.H>
#include <p9_hcd_common.H>
#include <p9_common_clk_ctrl_state.H>
#include "p9_hcd_l2_stopclocks.H"
#include "p9_hcd_cache_stopclocks.H"

//------------------------------------------------------------------------------
// Constant Definitions
//------------------------------------------------------------------------------

enum P9_HCD_CACHE_STOPCLOCKS_CONSTANTS
{
    CACHE_CLK_STOP_POLLING_HW_NS_DELAY     = 10000,
    CACHE_CLK_STOP_POLLING_SIM_CYCLE_DELAY = 320000,
    PB_PURGE_CACHE_STOP_POLLING_DELAY_HW_MILLISEC = 1000000ULL, // 1msec
    PB_PURGE_CACHE_STOP_POLLING_DELAY_SIM_CYCLES = 10000ULL,
    PB_PURGE_CACHE_STOP_POLLING_TIMEOUT = 10,
};

//------------------------------------------------------------------------------
// Procedure: Quad Clock Stop
//------------------------------------------------------------------------------

fapi2::ReturnCode
p9_hcd_cache_stopclocks(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
    const p9hcd::P9_HCD_CLK_CTRL_CONSTANTS      i_select_regions,
    const p9hcd::P9_HCD_EX_CTRL_CONSTANTS       i_select_ex)
{
    FAPI_INF(">>p9_hcd_cache_stopclocks: regions[%016llx] ex[%d]",
             i_select_regions, i_select_ex);
    fapi2::ReturnCode                              l_rc;
    fapi2::buffer<uint64_t>                        l_data64;
    fapi2::buffer<uint64_t>                        l_temp64;
    uint64_t                                       l_l3mask_pscom = 0;
    uint32_t                                       l_loops1ms;
    uint8_t                                        l_attr_chip_unit_pos = 0;
    uint8_t                                        l_attr_vdm_enable;
    uint8_t                                        l_is_mpipl = 0x0;
    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> l_sys;
    auto l_perv = i_target.getParent<fapi2::TARGET_TYPE_PERV>();
    auto l_chip = i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_MPIPL, l_sys, l_is_mpipl));

    if(l_is_mpipl)
    {
        // PB_PURGE related SCOMs should be added to the beginning of
        // p9_hcd_cache_stopclocks, these scoms should only be done if the clock
        // region including PBIEQ clock domain is being stopped, which
        // incidentally should always be the case for MPIPL
        l_data64.flush<0>();
        l_data64.setBit<30>();
        // Set bit 30 in EQ_QPPM_QCCR_SCOM2(100F01BF) Reg, Pulse to the
        // Powerbus logic in the Cache clock domain to request them to purge
        // their async buffers in preparation to power off the Quad
        FAPI_TRY(fapi2::putScom(i_target, EQ_QPPM_QCCR_SCOM2, l_data64));

        l_data64.flush<0>();
        uint32_t l_timeout = PB_PURGE_CACHE_STOP_POLLING_TIMEOUT;

        do
        {
            // Acknowledgement from Powerbus that the buffers are empty
            // and can safely be fenced & clocked off.
            FAPI_TRY(fapi2::getScom(i_target, EQ_QPPM_QCCR_SCOM, l_data64));
            bool l_poll_data = l_data64.getBit<31>();

            if(l_poll_data == 1)
            {
                break;
            }

            FAPI_TRY(fapi2::delay(PB_PURGE_CACHE_STOP_POLLING_DELAY_HW_MILLISEC,
                                  PB_PURGE_CACHE_STOP_POLLING_DELAY_SIM_CYCLES),
                     "Error from delay"); //1msec delay
        }
        while(--l_timeout != 0);

        // Error if Timeout happens
        FAPI_ASSERT((l_timeout != 0),
                    fapi2::QPPM_QCCR_PB_PURGE_DONE_LVL_TIMEOUT()
                    .set_TARGET(i_target)
                    .set_EQPPMQCCR(l_data64),
                    "QPPM_QCCR_PB_PURGE_DONE_LVL Reg bit 31 not set.");

        l_data64.flush<0>();
        l_data64.setBit<30>();
        FAPI_TRY(fapi2::putScom(i_target, EQ_QPPM_QCCR_SCOM1, l_data64));
    }

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDM_ENABLE,    l_sys,
                           l_attr_vdm_enable));
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_perv,
                           l_attr_chip_unit_pos));
//  l_attr_chip_unit_pos = l_attr_chip_unit_pos - p9hcd::PERV_TO_QUAD_POS_OFFSET;
    l_attr_chip_unit_pos = l_attr_chip_unit_pos - 0x10;

    if (i_select_regions & p9hcd::CLK_REGION_EX0_L3)
    {
        l_l3mask_pscom |= (BIT64(4) | BIT64(6) | BIT64(8));
    }

    if (i_select_regions & p9hcd::CLK_REGION_EX1_L3)
    {
        l_l3mask_pscom |= (BIT64(5) | BIT64(7) | BIT64(9));
    }

    // -----------------------------
    // Prepare to stop cache clocks
    // -----------------------------
    FAPI_DBG("Check PM_RESET_STATE_INDICATOR via GPMMR[15]");
    FAPI_TRY(getScom(i_target, EQ_PPM_GPMMR_SCOM, l_data64));

    if (!l_data64.getBit<15>())
    {
        FAPI_DBG("Gracefully turn off power management, if fail, continue anyways");
        /// @todo RTC158181 suspend_pm()
    }

    FAPI_DBG("Check cache clock controller status");
    l_rc = p9_common_clk_ctrl_state<fapi2::TARGET_TYPE_EQ>(i_target);

    if (l_rc)
    {
        FAPI_INF("Clock controller of this cache chiplet is inaccessible, return");
        goto fapi_try_exit;
    }

    FAPI_DBG("Check PERV clock status for access to CME via CLOCK_STAT[4]");
    FAPI_TRY(getScom(i_target, EQ_CLOCK_STAT_SL, l_data64));

    FAPI_DBG("Check PERV fence status for access to CME via CPLT_CTRL1[4]");
    FAPI_TRY(getScom(i_target, EQ_CPLT_CTRL1, l_temp64));

    if (l_data64.getBit<4>() == 0 && l_temp64.getBit<4>() == 0)
    {
        /// @todo RTC158181 disable l2 snoop? disable lco? assert refresh quiesce?
        FAPI_DBG("Assert L3 pscom masks via RING_FENCE_MASK_LATCH_REG[4-9]");
        FAPI_TRY(putScom(i_target, EQ_RING_FENCE_MASK_LATCH_REG, l_l3mask_pscom));
    }

    FAPI_DBG("Assert chiplet fence via NET_CTRL0[18]");
    FAPI_TRY(putScom(i_target, EQ_NET_CTRL0_WOR, MASK_SET(18)));

    // -------------------------------
    // Stop L2 clocks
    // -------------------------------

    if (i_select_ex)
        FAPI_EXEC_HWP(fapi2::current_err,
                      p9_hcd_l2_stopclocks,
                      i_target, i_select_ex);

    // -------------------------------
    // Stop cache clocks
    // -------------------------------

    FAPI_DBG("Clear all SCAN_REGION_TYPE bits");
    FAPI_TRY(putScom(i_target, EQ_SCAN_REGION_TYPE, MASK_ZERO));

    FAPI_DBG("Stop cache clocks via CLK_REGION");
    l_data64 = (p9hcd::CLK_STOP_CMD  |
                i_select_regions     |
                p9hcd::CLK_THOLD_ALL);
    FAPI_TRY(putScom(i_target, EQ_CLK_REGION, l_data64));

    FAPI_DBG("Poll for cache clocks stopped via CPLT_STAT0[8]");
    l_loops1ms = 1E6 / CACHE_CLK_STOP_POLLING_HW_NS_DELAY;

    do
    {
        fapi2::delay(CACHE_CLK_STOP_POLLING_HW_NS_DELAY,
                     CACHE_CLK_STOP_POLLING_SIM_CYCLE_DELAY);

        FAPI_TRY(getScom(i_target, EQ_CPLT_STAT0, l_data64));
    }
    while((l_data64.getBit<8>() != 1) && ((--l_loops1ms) != 0));

    FAPI_ASSERT((l_loops1ms != 0),
                fapi2::PMPROC_CACHECLKSTOP_TIMEOUT().set_EQCPLTSTAT(l_data64),
                "Cache Clock Stop Timeout");

    FAPI_DBG("Check cache clocks stopped");
    FAPI_TRY(getScom(i_target, EQ_CLOCK_STAT_SL, l_data64));

    FAPI_ASSERT((((~l_data64) & i_select_regions) == 0),
                fapi2::PMPROC_CACHECLKSTOP_FAILED().set_EQCLKSTAT(l_data64),
                "Cache Clock Stop Failed");
    FAPI_DBG("Cache clocks stopped now");

    // -------------------------------
    // Fence up
    // -------------------------------

    FAPI_DBG("Assert vital fence via CPLT_CTRL1[3]");
    FAPI_TRY(putScom(i_target, EQ_CPLT_CTRL1_OR, MASK_SET(3)));

    FAPI_DBG("Assert regional fences via CPLT_CTRL1[4-14]");
    FAPI_TRY(putScom(i_target, EQ_CPLT_CTRL1_OR, i_select_regions));

    // -------------------------------
    // Disable VDM
    // -------------------------------

    if (l_attr_vdm_enable == fapi2::ENUM_ATTR_VDM_ENABLE_ON)
    {
        FAPI_DBG("Drop vdm enable via QPPM_VDMCR[0]");
        FAPI_TRY(putScom(i_target, EQ_PPM_VDMCR_CLEAR, MASK_SET(0)));
    }

    // -------------------------------
    // Shutdown edram
    // -------------------------------
    // QCCR[0/4] EDRAM_ENABLE_DC
    // QCCR[1/5] EDRAM_VWL_ENABLE_DC
    // QCCR[2/6] L3_EX0/1_EDRAM_VROW_VBLH_ENABLE_DC
    // QCCR[3/7] EDRAM_VPP_ENABLE_DC

    if (i_select_regions & p9hcd::CLK_REGION_EX0_REFR)
    {
        FAPI_DBG("Sequence EX0 EDRAM disables via QPPM_QCCR[0-3]");
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(3)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(2)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(1)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(0)));
    }

    if (i_select_regions & p9hcd::CLK_REGION_EX1_REFR)
    {
        FAPI_DBG("Sequence EX1 EDRAM disables via QPPM_QCCR[4-7]");
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(7)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(6)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(5)));
        FAPI_TRY(putScom(i_target, EQ_QPPM_QCCR_WCLEAR, MASK_SET(4)));
    }

    // -------------------------------
    // Update QSSR and STOP history
    // -------------------------------

    FAPI_DBG("Set cache as stopped in QSSR");
    FAPI_TRY(putScom(l_chip, PU_OCB_OCI_QSSR_OR,
                     BIT64(l_attr_chip_unit_pos + 14)));

    FAPI_DBG("Set cache as stopped in STOP history register");
    FAPI_TRY(putScom(i_target, EQ_PPM_SSHSRC, BIT64(0)));

fapi_try_exit:

    FAPI_INF("<<p9_hcd_cache_stopclocks");
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (testabilitydriver@nokia.com)
**
** This file is part of Testability Driver Qt Agent
**
** If you have questions regarding the use of this file, please contact
** Nokia at testabilitydriver@nokia.com .
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QtPlugin>
#include <QDebug>

#include <testabilityutils.h>
#include <taslogger.h>
#include "tasqttraverse.h"

Q_EXPORT_PLUGIN2(qttraverse, TasQtTraverse)

/*!
    \class TasQtTraverse
    \brief TasQtTraverse traverse QWidgets and QGraphicsItems

    Traverse the basic qt ui elements
*/

/*!
    Constructor
*/
TasQtTraverse::TasQtTraverse(QObject* parent)
    :QObject(parent)
{
    mTraverseUtils = new TasTraverseUtils();
}

/*!
    Destructor
*/
TasQtTraverse::~TasQtTraverse()
{
    delete mTraverseUtils;
}

void TasQtTraverse::beginTraverse(TasCommand* command)
{
    mTraverseUtils->createFilter(command);
}

void TasQtTraverse::endTraverse()
{
    mTraverseUtils->clearFilter();
}

/*!
  Traverse QGraphicsItem based objects.
 */
void TasQtTraverse::traverseGraphicsItem(TasObject* objectInfo, QGraphicsItem* graphicsItem, TasCommand* command)
{
    bool embeddedApp = false;
    if (command && command->parameter("embedded") == "true") {
        embeddedApp = true;
    }

    objectInfo->addAttribute("objectType", embeddedApp? TYPE_WEB : TYPE_GRAPHICS_VIEW);
    objectInfo->setId(TestabilityUtils::graphicsItemId(graphicsItem));
    mTraverseUtils->addGraphicsItemCoordinates(objectInfo, graphicsItem, command);
    mTraverseUtils->printGraphicsItemProperties(objectInfo, graphicsItem);

}

/*!
  Traverse QObject based items.
*/
void TasQtTraverse::traverseObject(TasObject* objectInfo, QObject* object, TasCommand* command)
{
     // Embedded apps must use coordinates for operations, as the parent has no knowledge of the
    // Actual items
    bool embeddedApp = false;
    if (command && command->parameter("embedded") == "true") {
        embeddedApp = true;
    }
    //TasLogger::logger()->debug("TasQtTraverse::traverseObject in");
    mTraverseUtils->addObjectDetails(objectInfo, object);
    QGraphicsObject* graphicsObject = qobject_cast<QGraphicsObject*>(object);
    if(graphicsObject){
        objectInfo->addAttribute("objectType", embeddedApp? TYPE_WEB : TYPE_GRAPHICS_VIEW);
        mTraverseUtils->addGraphicsItemCoordinates(objectInfo, graphicsObject, command);
        mTraverseUtils->printGraphicsItemProperties(objectInfo, graphicsObject);

        //add details only for graphicsitems
        QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object);
        if(graphicsWidget){
            mTraverseUtils->addFont(objectInfo, graphicsWidget->font());
            // Elided format "this is a text" -> "this is a..." text for
            // items that have the "text" property.
            QVariant text = graphicsWidget->property("text");
            if (text.isValid()) {
                mTraverseUtils->addTextInfo(objectInfo, text.toString(), graphicsWidget->font(), graphicsWidget->size().width());

            }
            QVariant plainText = graphicsWidget->property("plainText");
            if (plainText.isValid()) {
                mTraverseUtils->addTextInfo(objectInfo, plainText.toString(), graphicsWidget->font(), graphicsWidget->size().width());
            }
        }
    }
    else{
        //make sure that we are dealing with a widget
        if (object->isWidgetType()){
            QWidget* widget = qobject_cast<QWidget*>(object);

            // Widgets inside proxies are forced into Web type
            // Operations are transformed into Web types
            QGraphicsProxyWidget* proxy = TestabilityUtils::parentProxy(widget);
            if (proxy) {
                objectInfo->addAttribute("objectType", TYPE_WEB);
            }
            else if(object != qApp){
                objectInfo->addAttribute("objectType", TYPE_STANDARD_VIEW );
            }
            addWidgetCoordinates(objectInfo, widget,command);
            mTraverseUtils->addFont(objectInfo, widget->font());
            //check is the widget a viewport to graphicsscene
            QWidget* parentWidget = widget->parentWidget();
            bool isViewPort = false;
            if(parentWidget && parentWidget->inherits("QGraphicsView")){
                QGraphicsView* view = qobject_cast<QGraphicsView*>(parentWidget);
                if(view->viewport() == widget){
                    isViewPort = true;
                }
            }
            //add transformation details
            QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(object);
            if(graphicsView){
                objectInfo->addBooleanAttribute("isTransformed", graphicsView->isTransformed());
                if(graphicsView->isTransformed()){
                    QTransform tr = graphicsView->transform();
                    objectInfo->addAttribute("transformM11",tr.m11());
                    objectInfo->addAttribute("transformM12",tr.m12());
                    objectInfo->addAttribute("transformM13",tr.m13());
                    objectInfo->addAttribute("transformM21",tr.m21());
                    objectInfo->addAttribute("transformM22",tr.m22());
                    objectInfo->addAttribute("transformM23",tr.m23());
                    objectInfo->addAttribute("transformM31",tr.m31());
                    objectInfo->addAttribute("transformM32",tr.m32());
                    objectInfo->addAttribute("transformM33",tr.m33());
                }
            }
            objectInfo->addBooleanAttribute("isViewPort", isViewPort);
// Add special window id attribute into qwidget atttributes
#if defined(Q_WS_X11)
            unsigned long wid = static_cast<unsigned long>(widget->winId());
            objectInfo->addAttribute("xWindow", (int)wid); // can this fail due to precision?
#endif

        } else {
            if(object != qApp){
                objectInfo->addAttribute("objectType", embeddedApp? TYPE_WEB : TYPE_STANDARD_VIEW );
            }
        }

    }
}

void TasQtTraverse::addWidgetCoordinates(TasObject* objectInfo, QWidget* widget, TasCommand* command)
{
    objectInfo->addBooleanAttribute("isWindow", widget->isWindow());

    QGraphicsProxyWidget* proxy = TestabilityUtils::parentProxy(widget);
    if (proxy) {
        //TasLogger::logger()->debug("TasQtTraverse::addWidgetCoordinates got proxy");
        //print window coordinates

        QRectF sceneRect = proxy->sceneBoundingRect();
        QGraphicsView* view = TestabilityUtils::getViewForItem(proxy);
        if(!view->viewportTransform().isIdentity()){
            QTransform transform = view->viewportTransform();
            sceneRect = transform.mapRect(sceneRect);
        }
        QPoint point = sceneRect.topLeft().toPoint();

        //Print screen coordinates
        QPoint windowPoint = widget->mapTo(widget->window(),QPoint(0, 0));
        windowPoint += point;
        objectInfo->addAttribute("x", windowPoint.x());
        objectInfo->addAttribute("y", windowPoint.y());

        objectInfo->addAttribute("x_absolute", windowPoint.x());
        objectInfo->addAttribute("y_absolute", windowPoint.y());
    }
    else {
        QPoint screenPoint;
        if (command && command->parameter("x_parent_absolute") != "" &&
            command->parameter("y_parent_absolute") != "") {
            //TasLogger::logger()->debug("TasQtTraverse::addWidgetCoordinates moving point");
            QPoint p(command->parameter("x_parent_absolute").toInt(),
                     command->parameter("y_parent_absolute").toInt());
            screenPoint = widget->mapToGlobal(p);

            objectInfo->addAttribute("x_absolute", screenPoint.x());
            objectInfo->addAttribute("y_absolute", screenPoint.y());

        } else {
            //TasLogger::logger()->debug("TasQtTraverse::addWidgetCoordinates using regular coords");
            screenPoint = widget->mapToGlobal(QPoint(0, 0));
            objectInfo->addAttribute("x_absolute", screenPoint.x());
            objectInfo->addAttribute("y_absolute", screenPoint.y());
        }
         //print window coordinates

        QPoint windowPoint = widget->window()->mapFromGlobal(screenPoint);
        objectInfo->addAttribute("x", windowPoint.x());
        objectInfo->addAttribute("y", windowPoint.y());

    }
    // Explicitly add width and height (property added changes name)
    objectInfo->addAttribute("width", widget->width());
    objectInfo->addAttribute("height", widget->height());
}

<commit_msg>remove proxy workaround<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (testabilitydriver@nokia.com)
**
** This file is part of Testability Driver Qt Agent
**
** If you have questions regarding the use of this file, please contact
** Nokia at testabilitydriver@nokia.com .
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QtPlugin>
#include <QDebug>

#include <testabilityutils.h>
#include <taslogger.h>
#include "tasqttraverse.h"

Q_EXPORT_PLUGIN2(qttraverse, TasQtTraverse)

/*!
    \class TasQtTraverse
    \brief TasQtTraverse traverse QWidgets and QGraphicsItems

    Traverse the basic qt ui elements
*/

/*!
    Constructor
*/
TasQtTraverse::TasQtTraverse(QObject* parent)
    :QObject(parent)
{
    mTraverseUtils = new TasTraverseUtils();
}

/*!
    Destructor
*/
TasQtTraverse::~TasQtTraverse()
{
    delete mTraverseUtils;
}

void TasQtTraverse::beginTraverse(TasCommand* command)
{
    mTraverseUtils->createFilter(command);
}

void TasQtTraverse::endTraverse()
{
    mTraverseUtils->clearFilter();
}

/*!
  Traverse QGraphicsItem based objects.
 */
void TasQtTraverse::traverseGraphicsItem(TasObject* objectInfo, QGraphicsItem* graphicsItem, TasCommand* command)
{
    bool embeddedApp = false;
    if (command && command->parameter("embedded") == "true") {
        embeddedApp = true;
    }

    objectInfo->addAttribute("objectType", embeddedApp? TYPE_WEB : TYPE_GRAPHICS_VIEW);
    objectInfo->setId(TestabilityUtils::graphicsItemId(graphicsItem));
    mTraverseUtils->addGraphicsItemCoordinates(objectInfo, graphicsItem, command);
    mTraverseUtils->printGraphicsItemProperties(objectInfo, graphicsItem);

}

/*!
  Traverse QObject based items.
*/
void TasQtTraverse::traverseObject(TasObject* objectInfo, QObject* object, TasCommand* command)
{
     // Embedded apps must use coordinates for operations, as the parent has no knowledge of the
    // Actual items
    bool embeddedApp = false;
    if (command && command->parameter("embedded") == "true") {
        embeddedApp = true;
    }
    //TasLogger::logger()->debug("TasQtTraverse::traverseObject in");
    mTraverseUtils->addObjectDetails(objectInfo, object);
    QGraphicsObject* graphicsObject = qobject_cast<QGraphicsObject*>(object);
    if(graphicsObject){
        objectInfo->addAttribute("objectType", embeddedApp? TYPE_WEB : TYPE_GRAPHICS_VIEW);
        mTraverseUtils->addGraphicsItemCoordinates(objectInfo, graphicsObject, command);
        mTraverseUtils->printGraphicsItemProperties(objectInfo, graphicsObject);

        //add details only for graphicsitems
        QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object);
        if(graphicsWidget){
            mTraverseUtils->addFont(objectInfo, graphicsWidget->font());
            // Elided format "this is a text" -> "this is a..." text for
            // items that have the "text" property.
            QVariant text = graphicsWidget->property("text");
            if (text.isValid()) {
                mTraverseUtils->addTextInfo(objectInfo, text.toString(), graphicsWidget->font(), graphicsWidget->size().width());

            }
            QVariant plainText = graphicsWidget->property("plainText");
            if (plainText.isValid()) {
                mTraverseUtils->addTextInfo(objectInfo, plainText.toString(), graphicsWidget->font(), graphicsWidget->size().width());
            }
        }
    }
    else{
        //make sure that we are dealing with a widget
        if (object->isWidgetType()){
            QWidget* widget = qobject_cast<QWidget*>(object);
            objectInfo->addAttribute("objectType", TYPE_STANDARD_VIEW );

            addWidgetCoordinates(objectInfo, widget,command);
            mTraverseUtils->addFont(objectInfo, widget->font());
            //check is the widget a viewport to graphicsscene
            QWidget* parentWidget = widget->parentWidget();
            bool isViewPort = false;
            if(parentWidget && parentWidget->inherits("QGraphicsView")){
                QGraphicsView* view = qobject_cast<QGraphicsView*>(parentWidget);
                if(view->viewport() == widget){
                    isViewPort = true;
                }
            }
            //add transformation details
            QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(object);
            if(graphicsView){
                objectInfo->addBooleanAttribute("isTransformed", graphicsView->isTransformed());
                if(graphicsView->isTransformed()){
                    QTransform tr = graphicsView->transform();
                    objectInfo->addAttribute("transformM11",tr.m11());
                    objectInfo->addAttribute("transformM12",tr.m12());
                    objectInfo->addAttribute("transformM13",tr.m13());
                    objectInfo->addAttribute("transformM21",tr.m21());
                    objectInfo->addAttribute("transformM22",tr.m22());
                    objectInfo->addAttribute("transformM23",tr.m23());
                    objectInfo->addAttribute("transformM31",tr.m31());
                    objectInfo->addAttribute("transformM32",tr.m32());
                    objectInfo->addAttribute("transformM33",tr.m33());
                }
            }
            objectInfo->addBooleanAttribute("isViewPort", isViewPort);
// Add special window id attribute into qwidget atttributes
#if defined(Q_WS_X11)
            unsigned long wid = static_cast<unsigned long>(widget->winId());
            objectInfo->addAttribute("xWindow", (int)wid); // can this fail due to precision?
#endif

        } else {
            if(object != qApp){
                objectInfo->addAttribute("objectType", embeddedApp? TYPE_WEB : TYPE_STANDARD_VIEW );
            }
        }

    }
}

void TasQtTraverse::addWidgetCoordinates(TasObject* objectInfo, QWidget* widget, TasCommand* command)
{
    objectInfo->addBooleanAttribute("isWindow", widget->isWindow());

    QGraphicsProxyWidget* proxy = TestabilityUtils::parentProxy(widget);
    if (proxy) {
        //TasLogger::logger()->debug("TasQtTraverse::addWidgetCoordinates got proxy");
        //print window coordinates

        QRectF sceneRect = proxy->sceneBoundingRect();
        QGraphicsView* view = TestabilityUtils::getViewForItem(proxy);
        if(!view->viewportTransform().isIdentity()){
            QTransform transform = view->viewportTransform();
            sceneRect = transform.mapRect(sceneRect);
        }
        QPoint point = sceneRect.topLeft().toPoint();

        //Print screen coordinates
        QPoint windowPoint = widget->mapTo(widget->window(),QPoint(0, 0));
        windowPoint += point;
        objectInfo->addAttribute("x", windowPoint.x());
        objectInfo->addAttribute("y", windowPoint.y());

        objectInfo->addAttribute("x_absolute", windowPoint.x());
        objectInfo->addAttribute("y_absolute", windowPoint.y());
    }
    else {
        QPoint screenPoint;
        if (command && command->parameter("x_parent_absolute") != "" &&
            command->parameter("y_parent_absolute") != "") {
            //TasLogger::logger()->debug("TasQtTraverse::addWidgetCoordinates moving point");
            QPoint p(command->parameter("x_parent_absolute").toInt(),
                     command->parameter("y_parent_absolute").toInt());
            screenPoint = widget->mapToGlobal(p);

            objectInfo->addAttribute("x_absolute", screenPoint.x());
            objectInfo->addAttribute("y_absolute", screenPoint.y());

        } else {
            //TasLogger::logger()->debug("TasQtTraverse::addWidgetCoordinates using regular coords");
            screenPoint = widget->mapToGlobal(QPoint(0, 0));
            objectInfo->addAttribute("x_absolute", screenPoint.x());
            objectInfo->addAttribute("y_absolute", screenPoint.y());
        }
         //print window coordinates

        QPoint windowPoint = widget->window()->mapFromGlobal(screenPoint);
        objectInfo->addAttribute("x", windowPoint.x());
        objectInfo->addAttribute("y", windowPoint.y());

    }
    // Explicitly add width and height (property added changes name)
    objectInfo->addAttribute("width", widget->width());
    objectInfo->addAttribute("height", widget->height());
}

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2020.  All rights reserved
 */
#ifndef _Stroika_Foundation_IO_Network_ConnectionOrientedStreamSocket_inl_
#define _Stroika_Foundation_IO_Network_ConnectionOrientedStreamSocket_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
namespace Stroika::Foundation::IO::Network {

    /*
     ********************************************************************************
     ******* Foundation::IO::Network::ConnectionOrientedStreamSocket::Ptr ***********
     ********************************************************************************
     */
    inline ConnectionOrientedStreamSocket::Ptr::Ptr (nullptr_t)
        : inherited{nullptr}
    {
    }
    inline ConnectionOrientedStreamSocket::Ptr::Ptr (shared_ptr<_IRep>&& rep)
        : inherited{move (rep)}
    {
    }
    inline ConnectionOrientedStreamSocket::Ptr::Ptr (const shared_ptr<_IRep>& rep)
        : inherited{rep}
    {
    }
    inline void ConnectionOrientedStreamSocket::Ptr::Close () const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        inherited::Close ();
    }
    inline void ConnectionOrientedStreamSocket::Ptr::Connect (const SocketAddress& sockAddr) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().Connect (sockAddr, nullopt, nullptr);
    }
    inline bool ConnectionOrientedStreamSocket::Ptr::Connect (const SocketAddress& sockAddr, unique_ptr<exception>* e) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _ref ().Connect (sockAddr, nullopt, e);
    }
    inline void ConnectionOrientedStreamSocket::Ptr::Connect (const SocketAddress& sockAddr, const Time::Duration& timeout) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().Connect (sockAddr, timeout, nullptr);
    }
    bool ConnectionOrientedStreamSocket::Ptr::Connect (const SocketAddress& sockAddr, const Time::Duration& timeout, unique_ptr<exception>* e) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _ref ().Connect (sockAddr, timeout, e);
    }
    inline size_t ConnectionOrientedStreamSocket::Ptr::Read (byte* intoStart, byte* intoEnd) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _ref ().Read (intoStart, intoEnd);
    }
    inline optional<size_t> ConnectionOrientedStreamSocket::Ptr::ReadNonBlocking (byte* intoStart, byte* intoEnd) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _ref ().ReadNonBlocking (intoStart, intoEnd);
    }
    inline void ConnectionOrientedStreamSocket::Ptr::Write (const byte* start, const byte* end) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().Write (start, end);
    }
    inline optional<IO::Network::SocketAddress> ConnectionOrientedStreamSocket::Ptr::GetPeerAddress () const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _cref ().GetPeerAddress ();
    }
    inline optional<Time::DurationSecondsType> ConnectionOrientedStreamSocket::Ptr::GetAutomaticTCPDisconnectOnClose () const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _cref ().GetAutomaticTCPDisconnectOnClose ();
    }
    inline void ConnectionOrientedStreamSocket::Ptr::SetAutomaticTCPDisconnectOnClose (const optional<Time::DurationSecondsType>& linger) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().SetAutomaticTCPDisconnectOnClose (linger);
    }
    inline auto ConnectionOrientedStreamSocket::Ptr::GetKeepAlives () const -> KeepAliveOptions
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _cref ().GetKeepAlives ();
    }
    inline void ConnectionOrientedStreamSocket::Ptr::SetKeepAlives (const KeepAliveOptions& keepAliveOptions) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().SetKeepAlives (keepAliveOptions);
    }
    inline shared_ptr<ConnectionOrientedStreamSocket::_IRep> ConnectionOrientedStreamSocket::Ptr::_GetSharedRep () const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return dynamic_pointer_cast<ConnectionOrientedStreamSocket::_IRep> (inherited::_GetSharedRep ());
    }
    inline ConnectionOrientedStreamSocket::_IRep& ConnectionOrientedStreamSocket::Ptr::_ref () const
    {
        AssertMember (&inherited::_ref (), _IRep);
        return *reinterpret_cast<_IRep*> (&inherited::_ref ());
    }
    inline const ConnectionOrientedStreamSocket::_IRep& ConnectionOrientedStreamSocket::Ptr::_cref () const
    {
        AssertMember (&inherited::_cref (), _IRep);
        return *reinterpret_cast<const _IRep*> (&inherited::_cref ());
    }

    /*
     ********************************************************************************
     ********* Foundation::IO::Network::ConnectionOrientedStreamSocket **************
     ********************************************************************************
     */
    inline ConnectionOrientedStreamSocket::Ptr ConnectionOrientedStreamSocket::NewConnection (const SocketAddress& sockAddr)
    {
        ConnectionOrientedStreamSocket::Ptr s = ConnectionOrientedStreamSocket::New (sockAddr.GetAddressFamily (), Socket::STREAM);
        s.Connect (sockAddr);
        return s;
    }

}

#endif /*_Stroika_Foundation_IO_Network_ConnectionOrientedStreamSocket_inl_*/
<commit_msg>fixed typo<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2020.  All rights reserved
 */
#ifndef _Stroika_Foundation_IO_Network_ConnectionOrientedStreamSocket_inl_
#define _Stroika_Foundation_IO_Network_ConnectionOrientedStreamSocket_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
namespace Stroika::Foundation::IO::Network {

    /*
     ********************************************************************************
     ******* Foundation::IO::Network::ConnectionOrientedStreamSocket::Ptr ***********
     ********************************************************************************
     */
    inline ConnectionOrientedStreamSocket::Ptr::Ptr (nullptr_t)
        : inherited{nullptr}
    {
    }
    inline ConnectionOrientedStreamSocket::Ptr::Ptr (shared_ptr<_IRep>&& rep)
        : inherited{move (rep)}
    {
    }
    inline ConnectionOrientedStreamSocket::Ptr::Ptr (const shared_ptr<_IRep>& rep)
        : inherited{rep}
    {
    }
    inline void ConnectionOrientedStreamSocket::Ptr::Close () const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        inherited::Close ();
    }
    inline void ConnectionOrientedStreamSocket::Ptr::Connect (const SocketAddress& sockAddr) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().Connect (sockAddr, nullopt, nullptr);
    }
    inline bool ConnectionOrientedStreamSocket::Ptr::Connect (const SocketAddress& sockAddr, unique_ptr<exception>* e) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _ref ().Connect (sockAddr, nullopt, e);
    }
    inline void ConnectionOrientedStreamSocket::Ptr::Connect (const SocketAddress& sockAddr, const Time::Duration& timeout) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().Connect (sockAddr, timeout, nullptr);
    }
    inline bool ConnectionOrientedStreamSocket::Ptr::Connect (const SocketAddress& sockAddr, const Time::Duration& timeout, unique_ptr<exception>* e) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _ref ().Connect (sockAddr, timeout, e);
    }
    inline size_t ConnectionOrientedStreamSocket::Ptr::Read (byte* intoStart, byte* intoEnd) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _ref ().Read (intoStart, intoEnd);
    }
    inline optional<size_t> ConnectionOrientedStreamSocket::Ptr::ReadNonBlocking (byte* intoStart, byte* intoEnd) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _ref ().ReadNonBlocking (intoStart, intoEnd);
    }
    inline void ConnectionOrientedStreamSocket::Ptr::Write (const byte* start, const byte* end) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().Write (start, end);
    }
    inline optional<IO::Network::SocketAddress> ConnectionOrientedStreamSocket::Ptr::GetPeerAddress () const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _cref ().GetPeerAddress ();
    }
    inline optional<Time::DurationSecondsType> ConnectionOrientedStreamSocket::Ptr::GetAutomaticTCPDisconnectOnClose () const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _cref ().GetAutomaticTCPDisconnectOnClose ();
    }
    inline void ConnectionOrientedStreamSocket::Ptr::SetAutomaticTCPDisconnectOnClose (const optional<Time::DurationSecondsType>& linger) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().SetAutomaticTCPDisconnectOnClose (linger);
    }
    inline auto ConnectionOrientedStreamSocket::Ptr::GetKeepAlives () const -> KeepAliveOptions
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return _cref ().GetKeepAlives ();
    }
    inline void ConnectionOrientedStreamSocket::Ptr::SetKeepAlives (const KeepAliveOptions& keepAliveOptions) const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        _ref ().SetKeepAlives (keepAliveOptions);
    }
    inline shared_ptr<ConnectionOrientedStreamSocket::_IRep> ConnectionOrientedStreamSocket::Ptr::_GetSharedRep () const
    {
        shared_lock<const AssertExternallySynchronizedLock> critSec{*this};
        return dynamic_pointer_cast<ConnectionOrientedStreamSocket::_IRep> (inherited::_GetSharedRep ());
    }
    inline ConnectionOrientedStreamSocket::_IRep& ConnectionOrientedStreamSocket::Ptr::_ref () const
    {
        AssertMember (&inherited::_ref (), _IRep);
        return *reinterpret_cast<_IRep*> (&inherited::_ref ());
    }
    inline const ConnectionOrientedStreamSocket::_IRep& ConnectionOrientedStreamSocket::Ptr::_cref () const
    {
        AssertMember (&inherited::_cref (), _IRep);
        return *reinterpret_cast<const _IRep*> (&inherited::_cref ());
    }

    /*
     ********************************************************************************
     ********* Foundation::IO::Network::ConnectionOrientedStreamSocket **************
     ********************************************************************************
     */
    inline ConnectionOrientedStreamSocket::Ptr ConnectionOrientedStreamSocket::NewConnection (const SocketAddress& sockAddr)
    {
        ConnectionOrientedStreamSocket::Ptr s = ConnectionOrientedStreamSocket::New (sockAddr.GetAddressFamily (), Socket::STREAM);
        s.Connect (sockAddr);
        return s;
    }

}

#endif /*_Stroika_Foundation_IO_Network_ConnectionOrientedStreamSocket_inl_*/
<|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 <vnl/vnl_cross.h>
#include <vnl/vnl_quaternion.h>
#include <mitkTensorModel.h>

using namespace mitk;

template< class ScalarType >
TensorModel< ScalarType >::TensorModel()
  : m_BValue(1000)
{
  m_KernelDirection[0]=1; m_KernelDirection[1]=0; m_KernelDirection[2]=0;
  m_KernelTensorMatrix.fill(0.0);
  m_KernelTensorMatrix[0][0] = 0.002;
  m_KernelTensorMatrix[1][1] = 0.0005;
  m_KernelTensorMatrix[2][2] = 0.0005;
}

template< class ScalarType >
TensorModel< ScalarType >::~TensorModel()
{

}

template< class ScalarType >
ScalarType TensorModel< ScalarType >::SimulateMeasurement(unsigned int dir)
{
  ScalarType signal = 0;

  if (dir>=this->m_GradientList.size())
    return signal;

  ItkTensorType tensor; tensor.Fill(0.0);
  this->m_FiberDirection.Normalize();
  vnl_vector_fixed<double, 3> axis = itk::CrossProduct(m_KernelDirection, this->m_FiberDirection).GetVnlVector(); axis.normalize();
  vnl_quaternion<double> rotation(axis, acos(m_KernelDirection*this->m_FiberDirection));
  rotation.normalize();
  vnl_matrix_fixed<double, 3, 3> matrix = rotation.rotation_matrix_transpose();

  vnl_matrix_fixed<double, 3, 3> tensorMatrix = matrix.transpose()*m_KernelTensorMatrix*matrix;
  tensor[0] = tensorMatrix[0][0]; tensor[1] = tensorMatrix[0][1]; tensor[2] = tensorMatrix[0][2];
  tensor[3] = tensorMatrix[1][1]; tensor[4] = tensorMatrix[1][2]; tensor[5] = tensorMatrix[2][2];

  GradientType g = this->m_GradientList[dir];
  float norm = g.GetNorm();
  ScalarType bVal = norm*norm;

  if (bVal>0.0001)
  {
    // calc g^T * D * g
    itk::DiffusionTensor3D< ScalarType > S;
    S[0] = g[0]*g[0];
    S[1] = g[1]*g[0];
    S[2] = g[2]*g[0];
    S[3] = g[1]*g[1];
    S[4] = g[2]*g[1];
    S[5] = g[2]*g[2];

    ScalarType D_scalar = tensor[0]*S[0] + tensor[1]*S[1] + tensor[2]*S[2] +
                          tensor[1]*S[1] + tensor[3]*S[3] + tensor[4]*S[4] +
                          tensor[2]*S[2] + tensor[4]*S[4] + tensor[5]*S[5];

    // check for corrupted tensor and generate signal
    if (D_scalar>=0)
      signal = std::exp ( -m_BValue * D_scalar );  // skip * bVal becaus bVal is already encoded in g^T*g (norm of g encodes b-value relative to baseline b-value m_BValue)
  }
  else
    signal = 1;

  return signal;
}

template< class ScalarType >
typename TensorModel< ScalarType >::PixelType TensorModel< ScalarType >::SimulateMeasurement()
{
  PixelType signal; signal.SetSize(this->m_GradientList.size()); signal.Fill(0.0);

  ItkTensorType tensor; tensor.Fill(0.0);
  this->m_FiberDirection.Normalize();
  vnl_vector_fixed<double, 3> axis = itk::CrossProduct(m_KernelDirection, this->m_FiberDirection).GetVnlVector(); axis.normalize();
  vnl_quaternion<double> rotation(axis, acos(m_KernelDirection*this->m_FiberDirection));
  rotation.normalize();
  vnl_matrix_fixed<double, 3, 3> matrix = rotation.rotation_matrix_transpose();

  vnl_matrix_fixed<double, 3, 3> tensorMatrix = matrix.transpose()*m_KernelTensorMatrix*matrix;
  tensor[0] = tensorMatrix[0][0]; tensor[1] = tensorMatrix[0][1]; tensor[2] = tensorMatrix[0][2];
  tensor[3] = tensorMatrix[1][1]; tensor[4] = tensorMatrix[1][2]; tensor[5] = tensorMatrix[2][2];

  for( unsigned int i=0; i<this->m_GradientList.size(); i++)
  {
    GradientType g = this->m_GradientList[i];
    ScalarType bVal = g.GetNorm(); bVal *= bVal;

    if (bVal>0.0001)
    {
      itk::DiffusionTensor3D< ScalarType > S;
      S[0] = g[0]*g[0]/bVal;
      S[1] = g[1]*g[0]/bVal;
      S[2] = g[2]*g[0]/bVal;
      S[3] = g[1]*g[1]/bVal;
      S[4] = g[2]*g[1]/bVal;
      S[5] = g[2]*g[2]/bVal;

      ScalarType D = tensor[0]*S[0] + tensor[1]*S[1] + tensor[2]*S[2] +
                     tensor[1]*S[1] + tensor[3]*S[3] + tensor[4]*S[4] +
                     tensor[2]*S[2] + tensor[4]*S[4] + tensor[5]*S[5];

      // check for corrupted tensor and generate signal
      if (D>=0)
        signal[i] = std::exp ( -m_BValue * bVal * D );
    }
    else
      signal[i] = 1;
  }

  return signal;
}
<commit_msg>Simplify tensor signal calculation<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 <vnl/vnl_cross.h>
#include <vnl/vnl_quaternion.h>
#include <mitkTensorModel.h>

using namespace mitk;

template< class ScalarType >
TensorModel< ScalarType >::TensorModel()
  : m_BValue(1000)
{
  m_KernelDirection[0]=1; m_KernelDirection[1]=0; m_KernelDirection[2]=0;
  m_KernelTensorMatrix.fill(0.0);
  m_KernelTensorMatrix[0][0] = 0.002;
  m_KernelTensorMatrix[1][1] = 0.0005;
  m_KernelTensorMatrix[2][2] = 0.0005;
}

template< class ScalarType >
TensorModel< ScalarType >::~TensorModel()
{

}

template< class ScalarType >
ScalarType TensorModel< ScalarType >::SimulateMeasurement(unsigned int dir)
{
  ScalarType signal = 0;

  if (dir>=this->m_GradientList.size())
    return signal;

  ItkTensorType tensor; tensor.Fill(0.0);
  this->m_FiberDirection.Normalize();
  vnl_vector_fixed<double, 3> axis = itk::CrossProduct(m_KernelDirection, this->m_FiberDirection).GetVnlVector(); axis.normalize();
  vnl_quaternion<double> rotation(axis, acos(m_KernelDirection*this->m_FiberDirection));
  rotation.normalize();
  vnl_matrix_fixed<double, 3, 3> matrix = rotation.rotation_matrix_transpose();

  vnl_matrix_fixed<double, 3, 3> tensorMatrix = matrix.transpose()*m_KernelTensorMatrix*matrix;
  tensor[0] = tensorMatrix[0][0]; tensor[1] = tensorMatrix[0][1]; tensor[2] = tensorMatrix[0][2];
  tensor[3] = tensorMatrix[1][1]; tensor[4] = tensorMatrix[1][2]; tensor[5] = tensorMatrix[2][2];

  GradientType g = this->m_GradientList[dir];
  float norm = g.GetNorm();
  ScalarType bVal = norm*norm;

  if (bVal>0.0001)
  {
    // calc g^T * D * g
    itk::DiffusionTensor3D< ScalarType > S;
    S[0] = g[0]*g[0];
    S[1] = g[1]*g[0];
    S[2] = g[2]*g[0];
    S[3] = g[1]*g[1];
    S[4] = g[2]*g[1];
    S[5] = g[2]*g[2];

    ScalarType D_scalar = tensor[0]*S[0] + tensor[1]*S[1] + tensor[2]*S[2] +
                          tensor[1]*S[1] + tensor[3]*S[3] + tensor[4]*S[4] +
                          tensor[2]*S[2] + tensor[4]*S[4] + tensor[5]*S[5];

    // check for corrupted tensor and generate signal
    if (D_scalar>=0)
      signal = std::exp ( -m_BValue * D_scalar );  // skip * bVal becaus bVal is already encoded in g^T*g (norm of g encodes b-value relative to baseline b-value m_BValue)
  }
  else
    signal = 1;

  return signal;
}

template< class ScalarType >
typename TensorModel< ScalarType >::PixelType TensorModel< ScalarType >::SimulateMeasurement()
{
  PixelType signal; signal.SetSize(this->m_GradientList.size()); signal.Fill(0.0);

  ItkTensorType tensor; tensor.Fill(0.0);
  this->m_FiberDirection.Normalize();
  vnl_vector_fixed<double, 3> axis = itk::CrossProduct(m_KernelDirection, this->m_FiberDirection).GetVnlVector(); axis.normalize();
  vnl_quaternion<double> rotation(axis, acos(m_KernelDirection*this->m_FiberDirection));
  rotation.normalize();
  vnl_matrix_fixed<double, 3, 3> matrix = rotation.rotation_matrix_transpose();

  vnl_matrix_fixed<double, 3, 3> tensorMatrix = matrix.transpose()*m_KernelTensorMatrix*matrix;
  tensor[0] = tensorMatrix[0][0]; tensor[1] = tensorMatrix[0][1]; tensor[2] = tensorMatrix[0][2];
  tensor[3] = tensorMatrix[1][1]; tensor[4] = tensorMatrix[1][2]; tensor[5] = tensorMatrix[2][2];

  for( unsigned int i=0; i<this->m_GradientList.size(); i++)
  {
    GradientType g = this->m_GradientList[i];
    ScalarType bVal = g.GetNorm(); bVal *= bVal;

    if (bVal>0.0001)
    {
      // calc g^T * D * g
      itk::DiffusionTensor3D< ScalarType > S;
      S[0] = g[0]*g[0];
      S[1] = g[1]*g[0];
      S[2] = g[2]*g[0];
      S[3] = g[1]*g[1];
      S[4] = g[2]*g[1];
      S[5] = g[2]*g[2];

      ScalarType D_scalar = tensor[0]*S[0] + tensor[1]*S[1] + tensor[2]*S[2] +
                     tensor[1]*S[1] + tensor[3]*S[3] + tensor[4]*S[4] +
                     tensor[2]*S[2] + tensor[4]*S[4] + tensor[5]*S[5];

      // check for corrupted tensor and generate signal
      if (D_scalar>=0)
        signal[i] = std::exp ( -m_BValue * D_scalar );// skip * bVal becaus bVal is already encoded in g^T*g (norm of g encodes b-value relative to baseline b-value m_BValue)
    }
    else
      signal[i] = 1;
  }

  return signal;
}
<|endoftext|>