<commit_before>#include <math.h>

#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeTorus.hxx>
#include <SMESH_Gen.hxx>
#include <StdMeshers_AutomaticLength.hxx>
#include <StdMeshers_TrianglePreference.hxx>
#include <StdMeshers_NumberOfSegments.hxx>
#include <StdMeshers_Regular_1D.hxx>
#include <StdMeshers_MEFISTO_2D.hxx>
#include <gtest/gtest.h>

TEST(MeshBasicGeometriesSuite, testMeshBox)
{
    // create a box, mixing integers and floats
    BRepPrimAPI_MakeBox my_box(10.,10.,10.);
    my_box.Build();
    ASSERT_TRUE(my_box.IsDone());
    // create the Mesh
    SMESH_Gen* meshgen = new SMESH_Gen();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    // set geometry to be meshed
    mesh->ShapeToMesh(my_box.Shape());
    ASSERT_TRUE(mesh->HasShapeToMesh());
    // check bounding box. It should be 10.sqrt(3)==17.32050807568877
    double diagonal_size = mesh->GetShapeDiagonalSize(mesh->GetShapeToMesh());
    ASSERT_GT(diagonal_size, 17.320508);
    ASSERT_LT(diagonal_size, 17.320509);
    // create and add hypothesis
    StdMeshers_AutomaticLength* hyp1d_0 = new StdMeshers_AutomaticLength(0,0,meshgen);
    StdMeshers_NumberOfSegments* hyp1d_1 = new StdMeshers_NumberOfSegments(1,0,meshgen);
    hyp1d_1->SetNumberOfSegments(1);
    StdMeshers_Regular_1D* hyp1d_2 = new StdMeshers_Regular_1D(2,0,meshgen);
    StdMeshers_TrianglePreference* hyp2d = new StdMeshers_TrianglePreference(3,0,meshgen);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 0);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 1);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 2);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 3);
    // compute the mesh
    meshgen->Compute(*mesh, mesh->GetShapeToMesh());
    // free memory
    delete meshgen;
    delete mesh;
}

TEST(MeshBasicGeometriesSuite, testMeshBoxMEFISTO2)
{
    // create a box, mixing integers and floats
    BRepPrimAPI_MakeBox my_box(10.,10.,10.);
    my_box.Build();
    ASSERT_TRUE(my_box.IsDone());
    // create the Mesh
    SMESH_Gen* meshgen = new SMESH_Gen();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    // set geometry to be meshed
    mesh->ShapeToMesh(my_box.Shape());
    ASSERT_TRUE(mesh->HasShapeToMesh());
    // check bounding box. It should be 10.sqrt(3)==17.32050807568877
    double diagonal_size = mesh->GetShapeDiagonalSize(mesh->GetShapeToMesh());
    ASSERT_GT(diagonal_size, 17.320508);
    ASSERT_LT(diagonal_size, 17.320509);
    // create and add hypothesis
    StdMeshers_AutomaticLength* hyp1d = new StdMeshers_AutomaticLength(0,0,meshgen);
    StdMeshers_TrianglePreference* hyp2d = new StdMeshers_TrianglePreference(1,0,meshgen);
    StdMeshers_MEFISTO_2D* mef2d = new StdMeshers_MEFISTO_2D(2,0,meshgen) ;
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 0);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 1);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 2);
    // compute the mesh
    meshgen->Compute(*mesh, mesh->GetShapeToMesh());
    // free memory
    delete meshgen;
    delete mesh;
}

TEST(MeshBasicGeometriesSuite, testMeshSphere)
{
    // the same as the previous test, but with a sphere
    BRepPrimAPI_MakeSphere my_sphere(10.);
    my_sphere.Build();
    ASSERT_TRUE(my_sphere.IsDone());
    // create the Mesh
    SMESH_Gen* meshgen = new SMESH_Gen();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    // set geometry to be meshed
    mesh->ShapeToMesh(my_sphere.Shape());
    ASSERT_TRUE(mesh->HasShapeToMesh());
    // compute the mesh
    meshgen->Compute(*mesh, mesh->GetShapeToMesh());
    // free memory
    delete meshgen;
    delete mesh;
}

TEST(MeshBasicGeometriesSuite, testMeshTorus)
{
    // the same as the previous test, but with a sphere
    BRepPrimAPI_MakeTorus my_torus(10., 20.);
    my_torus.Build();
    ASSERT_TRUE(my_torus.IsDone());
    // create the Mesh
    SMESH_Gen* meshgen = new SMESH_Gen();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    // set geometry to be meshed
    mesh->ShapeToMesh(my_torus.Shape());
    ASSERT_TRUE(mesh->HasShapeToMesh());
    // compute the mesh
    meshgen->Compute(*mesh, mesh->GetShapeToMesh());
    // free memory
    delete meshgen;
    delete mesh;
}

int main(int argc, char **argv){
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>Fixed MeshBasicGeometries example<commit_after>#include <math.h>

#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeTorus.hxx>
#include <SMESH_Gen.hxx>
#include <StdMeshers_AutomaticLength.hxx>
#include <StdMeshers_Arithmetic1D.hxx>
#include <StdMeshers_TrianglePreference.hxx>
#include <StdMeshers_NumberOfSegments.hxx>
#include <StdMeshers_Regular_1D.hxx>
#include <StdMeshers_MEFISTO_2D.hxx>
#include <StdMeshers_Quadrangle_2D.hxx>

#include <gtest/gtest.h>

TEST(MeshBasicGeometriesSuite, testMeshBox)
{
    // create a box, mixing integers and floats
    BRepPrimAPI_MakeBox my_box(10.,10.,10.);
    my_box.Build();
    ASSERT_TRUE(my_box.IsDone());
    // create the Mesh
    SMESH_Gen* meshgen = new SMESH_Gen();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    // set geometry to be meshed
    mesh->ShapeToMesh(my_box.Shape());
    ASSERT_TRUE(mesh->HasShapeToMesh());
    // check bounding box. It should be 10.sqrt(3)==17.32050807568877
    double diagonal_size = mesh->GetShapeDiagonalSize(mesh->GetShapeToMesh());
    ASSERT_GT(diagonal_size, 17.320508);
    ASSERT_LT(diagonal_size, 17.320509);
    // create and add hypothesis
    StdMeshers_AutomaticLength* hyp1d_0 = new StdMeshers_AutomaticLength(0,0,meshgen);
    StdMeshers_NumberOfSegments* hyp1d_1 = new StdMeshers_NumberOfSegments(1,0,meshgen);
    hyp1d_1->SetNumberOfSegments(1);
    StdMeshers_Regular_1D* hyp1d_2 = new StdMeshers_Regular_1D(2,0,meshgen);
    StdMeshers_TrianglePreference* hyp2d = new StdMeshers_TrianglePreference(3,0,meshgen);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 0);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 1);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 2);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 3);
    // compute the mesh
    meshgen->Compute(*mesh, mesh->GetShapeToMesh());
    // free memory
    delete meshgen;
    delete mesh;
}

TEST(MeshBasicGeometriesSuite, testMeshBoxMEFISTO2)
{
    // create a box, mixing integers and floats
    BRepPrimAPI_MakeBox my_box(10.,10.,10.);
    my_box.Build();
    ASSERT_TRUE(my_box.IsDone());
    // create the Mesh
    SMESH_Gen* meshgen = new SMESH_Gen();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    // set geometry to be meshed
    mesh->ShapeToMesh(my_box.Shape());
    ASSERT_TRUE(mesh->HasShapeToMesh());
    // check bounding box. It should be 10.sqrt(3)==17.32050807568877
    double diagonal_size = mesh->GetShapeDiagonalSize(mesh->GetShapeToMesh());
    ASSERT_GT(diagonal_size, 17.320508);
    ASSERT_LT(diagonal_size, 17.320509);
    // create and add hypothesis
    StdMeshers_Arithmetic1D* hyp1d = new StdMeshers_Arithmetic1D(0,0,meshgen);
    hyp1d->SetLength(0.1, false); // the smallest distance between 2 points
    hyp1d->SetLength(0.5, true);  // the longest distance between 2 points
    StdMeshers_Regular_1D* an1DAlgo = new StdMeshers_Regular_1D(1, 0, meshgen); // interpolation
    StdMeshers_TrianglePreference* hyp2d = new StdMeshers_TrianglePreference(2,0,meshgen);
    StdMeshers_MEFISTO_2D* mef2d = new StdMeshers_MEFISTO_2D(3,0,meshgen) ;
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 0);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 1);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 2);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 3);
    // compute the mesh
    meshgen->Compute(*mesh, mesh->GetShapeToMesh());
    // free memory
    delete meshgen;
    delete mesh;
}

TEST(MeshBasicGeometriesSuite, testMeshSphere)
{
    // the same as the previous test, but with a sphere
    BRepPrimAPI_MakeSphere my_sphere(10.);
    my_sphere.Build();
    ASSERT_TRUE(my_sphere.IsDone());
    // create the Mesh
    SMESH_Gen* meshgen = new SMESH_Gen();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    // set geometry to be meshed
    mesh->ShapeToMesh(my_sphere.Shape());
    ASSERT_TRUE(mesh->HasShapeToMesh());
    // compute the mesh
    meshgen->Compute(*mesh, mesh->GetShapeToMesh());
    // free memory
    delete meshgen;
    delete mesh;
}

TEST(MeshBasicGeometriesSuite, testMeshQuadrangleTorus)
{
    // the same as the previous test, but with a sphere
    BRepPrimAPI_MakeTorus my_torus(10., 20.);
    my_torus.Build();
    ASSERT_TRUE(my_torus.IsDone());
    // create the Mesh
    SMESH_Gen* meshgen = new SMESH_Gen();
    SMESH_Mesh* mesh = meshgen->CreateMesh(0, true);
    // 1D
    StdMeshers_Arithmetic1D* hyp1d = new StdMeshers_Arithmetic1D(0,0,meshgen);
    hyp1d->SetLength(0.1, false); // the smallest distance between 2 points
    hyp1d->SetLength(0.5, true);  // the longest distance between 2 points
    StdMeshers_Regular_1D* an1DAlgo = new StdMeshers_Regular_1D(1, 0, meshgen); // interpolation
    StdMeshers_Quadrangle_2D *a2dAlgo = new StdMeshers_Quadrangle_2D(2, 0, meshgen);
    // add hypothesis
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 0);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 1);
    mesh->AddHypothesis(mesh->GetShapeToMesh(), 2);
    // set geometry to be meshed
    mesh->ShapeToMesh(my_torus.Shape());
    ASSERT_TRUE(mesh->HasShapeToMesh());
    // compute the mesh
    meshgen->Compute(*mesh, mesh->GetShapeToMesh());
    // free memory
    delete meshgen;
    delete mesh;
}

int main(int argc, char **argv){
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "components/RatingComponent.h"
#include "Renderer.h"
#include "Window.h"
#include "Util.h"
#include "resources/SVGResource.h"

RatingComponent::RatingComponent(Window* window) : GuiComponent(window)
{
	mFilledTexture = TextureResource::get(":/star_filled.svg", true);
	mUnfilledTexture = TextureResource::get(":/star_unfilled.svg", true);
	mValue = 0.5f;
	mSize << 64 * NUM_RATING_STARS, 64;
	updateVertices();
}

void RatingComponent::setValue(const std::string& value)
{
	if(value.empty())
	{
		mValue = 0.0f;
	}else{
		mValue = stof(value);
		if(mValue > 1.0f)
			mValue = 1.0f;
		else if(mValue < 0.0f)
			mValue = 0.0f;
	}

	updateVertices();
}

std::string RatingComponent::getValue() const
{
	return std::to_string((long double)mValue);
}

void RatingComponent::onSizeChanged()
{
	if(mSize.y() == 0)
		mSize[1] = mSize.x() / NUM_RATING_STARS;
	else if(mSize.x() == 0)
		mSize[0] = mSize.y() * NUM_RATING_STARS;

	auto filledSVG = dynamic_cast<SVGResource*>(mFilledTexture.get());
	auto unfilledSVG = dynamic_cast<SVGResource*>(mUnfilledTexture.get());

	if(mSize.y() > 0)
	{
		size_t heightPx = (size_t)round(mSize.y());
		if(filledSVG)
			filledSVG->rasterizeAt(heightPx, heightPx);
		if(unfilledSVG)
			unfilledSVG->rasterizeAt(heightPx, heightPx);
	}

	updateVertices();
}

void RatingComponent::updateVertices()
{
	const float numStars = NUM_RATING_STARS;

	const float h = round(getSize().y()); // is the same as a single star's width
	const float w = round(h * mValue * numStars);
	const float fw = round(h * numStars);

	mVertices[0].pos << 0.0f, 0.0f;
		mVertices[0].tex << 0.0f, 1.0f;
	mVertices[1].pos << w, h;
		mVertices[1].tex << mValue * numStars, 0.0f;
	mVertices[2].pos << 0.0f, h;
		mVertices[2].tex << 0.0f, 0.0f;

	mVertices[3] = mVertices[0];
	mVertices[4].pos << w, 0.0f;
		mVertices[4].tex << mValue * numStars, 1.0f;
	mVertices[5] = mVertices[1];

	mVertices[6] = mVertices[4];
	mVertices[7].pos << fw, h;
		mVertices[7].tex << numStars, 0.0f;
	mVertices[8] = mVertices[1];

	mVertices[9] = mVertices[6];
	mVertices[10].pos << fw, 0.0f;
		mVertices[10].tex << numStars, 1.0f;
	mVertices[11] = mVertices[7];
}

void RatingComponent::render(const Eigen::Affine3f& parentTrans)
{
	Eigen::Affine3f trans = roundMatrix(parentTrans * getTransform());
	Renderer::setMatrix(trans);

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glColor4ub(255, 255, 255, getOpacity());

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].pos);
	glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].tex);

	mFilledTexture->bind();
	glDrawArrays(GL_TRIANGLES, 0, 6);

	mUnfilledTexture->bind();
	glDrawArrays(GL_TRIANGLES, 6, 6);

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_BLEND);

	glColor4ub(255, 255, 255, 255);

	renderChildren(trans);
}

bool RatingComponent::input(InputConfig* config, Input input)
{
	if(config->isMappedTo("a", input) && input.value != 0)
	{
		mValue += 1.f / NUM_RATING_STARS;
		if(mValue > 1.0f)
			mValue = 0.0f;

		updateVertices();
	}

	return GuiComponent::input(config, input);
}

void RatingComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties)
{
	GuiComponent::applyTheme(theme, view, element, properties);

	using namespace ThemeFlags;

	const ThemeData::ThemeElement* elem = theme->getElement(view, element, "rating");
	if(!elem)
		return;

	bool imgChanged = false;
	if(properties & PATH && elem->has("filledPath"))
	{
		mFilledTexture = TextureResource::get(elem->get<std::string>("filledPath"), true);
		imgChanged = true;
	}
	if(properties & PATH && elem->has("unfilledPath"))
	{
		mUnfilledTexture = TextureResource::get(elem->get<std::string>("unfilledPath"), true);
		imgChanged = true;
	}

	if(imgChanged)
		onSizeChanged();
}

std::vector<HelpPrompt> RatingComponent::getHelpPrompts()
{
	std::vector<HelpPrompt> prompts;
	prompts.push_back(HelpPrompt("a", "add star"));
	return prompts;
}
<commit_msg>Fixed ratings mysteriously not working on certain locales (e.g. German).<commit_after>#include "components/RatingComponent.h"
#include "Renderer.h"
#include "Window.h"
#include "Util.h"
#include "resources/SVGResource.h"

RatingComponent::RatingComponent(Window* window) : GuiComponent(window)
{
	mFilledTexture = TextureResource::get(":/star_filled.svg", true);
	mUnfilledTexture = TextureResource::get(":/star_unfilled.svg", true);
	mValue = 0.5f;
	mSize << 64 * NUM_RATING_STARS, 64;
	updateVertices();
}

void RatingComponent::setValue(const std::string& value)
{
	if(value.empty())
	{
		mValue = 0.0f;
	}else{
		mValue = stof(value);
		if(mValue > 1.0f)
			mValue = 1.0f;
		else if(mValue < 0.0f)
			mValue = 0.0f;
	}

	updateVertices();
}

std::string RatingComponent::getValue() const
{
	// do not use std::to_string here as it will use the current locale
	// and that sometimes encodes decimals as commas
	std::stringstream ss;
	ss << mValue;
	return ss.str();
}

void RatingComponent::onSizeChanged()
{
	if(mSize.y() == 0)
		mSize[1] = mSize.x() / NUM_RATING_STARS;
	else if(mSize.x() == 0)
		mSize[0] = mSize.y() * NUM_RATING_STARS;

	auto filledSVG = dynamic_cast<SVGResource*>(mFilledTexture.get());
	auto unfilledSVG = dynamic_cast<SVGResource*>(mUnfilledTexture.get());

	if(mSize.y() > 0)
	{
		size_t heightPx = (size_t)round(mSize.y());
		if(filledSVG)
			filledSVG->rasterizeAt(heightPx, heightPx);
		if(unfilledSVG)
			unfilledSVG->rasterizeAt(heightPx, heightPx);
	}

	updateVertices();
}

void RatingComponent::updateVertices()
{
	const float numStars = NUM_RATING_STARS;

	const float h = round(getSize().y()); // is the same as a single star's width
	const float w = round(h * mValue * numStars);
	const float fw = round(h * numStars);

	mVertices[0].pos << 0.0f, 0.0f;
		mVertices[0].tex << 0.0f, 1.0f;
	mVertices[1].pos << w, h;
		mVertices[1].tex << mValue * numStars, 0.0f;
	mVertices[2].pos << 0.0f, h;
		mVertices[2].tex << 0.0f, 0.0f;

	mVertices[3] = mVertices[0];
	mVertices[4].pos << w, 0.0f;
		mVertices[4].tex << mValue * numStars, 1.0f;
	mVertices[5] = mVertices[1];

	mVertices[6] = mVertices[4];
	mVertices[7].pos << fw, h;
		mVertices[7].tex << numStars, 0.0f;
	mVertices[8] = mVertices[1];

	mVertices[9] = mVertices[6];
	mVertices[10].pos << fw, 0.0f;
		mVertices[10].tex << numStars, 1.0f;
	mVertices[11] = mVertices[7];
}

void RatingComponent::render(const Eigen::Affine3f& parentTrans)
{
	Eigen::Affine3f trans = roundMatrix(parentTrans * getTransform());
	Renderer::setMatrix(trans);

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glColor4ub(255, 255, 255, getOpacity());

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].pos);
	glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &mVertices[0].tex);

	mFilledTexture->bind();
	glDrawArrays(GL_TRIANGLES, 0, 6);

	mUnfilledTexture->bind();
	glDrawArrays(GL_TRIANGLES, 6, 6);

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_BLEND);

	glColor4ub(255, 255, 255, 255);

	renderChildren(trans);
}

bool RatingComponent::input(InputConfig* config, Input input)
{
	if(config->isMappedTo("a", input) && input.value != 0)
	{
		mValue += 1.f / NUM_RATING_STARS;
		if(mValue > 1.0f)
			mValue = 0.0f;

		updateVertices();
	}

	return GuiComponent::input(config, input);
}

void RatingComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties)
{
	GuiComponent::applyTheme(theme, view, element, properties);

	using namespace ThemeFlags;

	const ThemeData::ThemeElement* elem = theme->getElement(view, element, "rating");
	if(!elem)
		return;

	bool imgChanged = false;
	if(properties & PATH && elem->has("filledPath"))
	{
		mFilledTexture = TextureResource::get(elem->get<std::string>("filledPath"), true);
		imgChanged = true;
	}
	if(properties & PATH && elem->has("unfilledPath"))
	{
		mUnfilledTexture = TextureResource::get(elem->get<std::string>("unfilledPath"), true);
		imgChanged = true;
	}

	if(imgChanged)
		onSizeChanged();
}

std::vector<HelpPrompt> RatingComponent::getHelpPrompts()
{
	std::vector<HelpPrompt> prompts;
	prompts.push_back(HelpPrompt("a", "add star"));
	return prompts;
}
<|endoftext|>


<commit_before>#include "MicroBit.h"

extern "C" {
    void mp_run(void);

    void microbit_display_event(void);
}

static void event_listener(MicroBitEvent evt) {
    if (evt.value == MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE) {
        microbit_display_event();
    }
}

void app_main() {
    uBit.MessageBus.listen(MICROBIT_ID_DISPLAY,
        MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE, event_listener);
    while (1) {
        mp_run();
    }
}
<commit_msg>Add commented-out debugging printfs for examining memory layout.<commit_after>#include "MicroBit.h"

extern "C" {
    void mp_run(void);

    void microbit_display_event(void);
}

static void event_listener(MicroBitEvent evt) {
    if (evt.value == MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE) {
        microbit_display_event();
    }
}

void app_main() {
    /*
    // debugging: print memory layout
    extern uint32_t __data_start__, __data_end__;
    extern uint32_t __bss_start__, __bss_end__;
    extern uint32_t __HeapLimit, __StackLimit, __StackTop;
    printf("__data_start__ = %p\r\n", &__data_start__);
    printf("__data_end__   = %p\r\n", &__data_end__);
    printf("__bss_start_ _ = %p\r\n", &__bss_start__);
    printf("__bss_end__    = %p\r\n", &__bss_end__);
    printf("__HeapLimit    = %p\r\n", &__HeapLimit);
    printf("__StackLimit   = %p\r\n", &__StackLimit);
    printf("__StackTop     = %p\r\n", &__StackTop);
    */

    uBit.MessageBus.listen(MICROBIT_ID_DISPLAY,
        MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE, event_listener);
    while (1) {
        mp_run();
    }
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used 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.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore/QString>
#include <QtTest/QtTest>
#include <QtCore/QCoreApplication>

#include "qnfctestcommon.h"
#include "qnfctestutil.h"

#include <qnearfieldmanager.h>
#include <qnearfieldtarget.h>
#include <qndefnfctextrecord.h>
#include <qndefnfcurirecord.h>
#include <qndefmessage.h>
#include <qndefrecord.h>

QTM_USE_NAMESPACE

Q_DECLARE_METATYPE(QNearFieldTarget*)
Q_DECLARE_METATYPE(QNearFieldTarget::Type)
Q_DECLARE_METATYPE(QNdefFilter)

class tst_QNearFieldManager : public QObject
{
    Q_OBJECT

public:
    tst_QNearFieldManager();

private Q_SLOTS:
    void initTestCase();
    void cleanupTestCase();
    void targetDetected();
    void targetDetected_data();
    void unregisterTargetDetectedHandler();
    void registerTargetDetectedHandler();
    void registerTargetDetectedHandler_filter_data();
    void registerTargetDetectedHandler_filter();
    void registerTargetDetectedHandler_filter_negtive();
    void registerTargetDetectedHandler_filter_negtive_data();
};

tst_QNearFieldManager::tst_QNearFieldManager()
{
    qRegisterMetaType<QNdefMessage>("QNdefMessage");
    qRegisterMetaType<QNearFieldTarget *>("QNearFieldTarget*");
}

void tst_QNearFieldManager::initTestCase()
{
    qRegisterMetaType<QNearFieldTarget *>("QNearFieldTarget *");
}

void tst_QNearFieldManager::cleanupTestCase()
{
}

/*!
 Description: Unit test for NFC target detected and lost

 TestScenario: 1. Touch and remove llcp device/Type1/Type2/Type3/Type4 tag one by one

 TestExpectedResults: 1. llcp device/Type1/Type2/Type3/Type4 tag detected/lost signal can be received
*/

void tst_QNearFieldManager::targetDetected()
{
    QFETCH(QNearFieldTarget::Type, type);
    QFETCH(QString, hint);

    QNearFieldManager nfcManager;

    QSignalSpy targetDetectedSpy(&nfcManager, SIGNAL(targetDetected(QNearFieldTarget*)));
    QSignalSpy targetLostSpy(&nfcManager, SIGNAL(targetLost(QNearFieldTarget*)));

    nfcManager.startTargetDetection(type);
    QNfcTestUtil::ShowMessage(hint);
    QTRY_VERIFY(!targetDetectedSpy.isEmpty());

    QNearFieldTarget *target = targetDetectedSpy.first().at(0).value<QNearFieldTarget *>();

    QSignalSpy disconnectedSpy(target, SIGNAL(disconnected()));
    QVERIFY(target);

    QVERIFY(!target->uid().isEmpty());

    if (type != QNearFieldTarget::AnyTarget)
    {
        QCOMPARE(target->type(), type);
    }

    QNfcTestUtil::ShowMessage("please remove the target");

    QTRY_VERIFY(!targetLostSpy.isEmpty());

    QNearFieldTarget *lostTarget = targetLostSpy.first().at(0).value<QNearFieldTarget *>();

    QCOMPARE(target, lostTarget);

    QVERIFY(!disconnectedSpy.isEmpty());

    nfcManager.stopTargetDetection();
}

void tst_QNearFieldManager::targetDetected_data()
{
    QTest::addColumn<QNearFieldTarget::Type>("type");
    QTest::addColumn<QString>("hint");
    QTest::newRow("llcp device") << QNearFieldTarget::AnyTarget << "Please touch llcp device";
    QTest::newRow("NfcTagType1") << QNearFieldTarget::NfcTagType1 << "Please touch tag type1";
    QTest::newRow("NfcTagType2") << QNearFieldTarget::NfcTagType1 << "Please touch tag type2";
    QTest::newRow("NfcTagType3") << QNearFieldTarget::NfcTagType1 << "Please touch tag type3";
    QTest::newRow("NfcTagType4") << QNearFieldTarget::NfcTagType1 << "Please touch tag type4";
}

/*!
 Description: Unit test for NFC unregisterTargetDetectedHandler function

 TestScenario: 1.

 TestExpectedResults: 1. return false
*/

void tst_QNearFieldManager::unregisterTargetDetectedHandler()
{
    QNearFieldManager manager;

    QVERIFY(!manager.unregisterTargetDetectedHandler(-1));
    QVERIFY(!manager.unregisterTargetDetectedHandler(0));
}

class MessageListener : public QObject
{
    Q_OBJECT

signals:
    void matchedNdefMessage(const QNdefMessage &message, QNearFieldTarget *target);
};

/*!
 Description: Unit test for NFC registerTargetDetectedHandler function

 TestScenario: 1. Symbian backend does not support registerTargetDetectedHandler without a QNdefFilter

 TestExpectedResults: 1. return -1
*/
void tst_QNearFieldManager::registerTargetDetectedHandler()
{
    QNearFieldManager manager;

    MessageListener listener;
    QSignalSpy messageSpy(&listener, SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    int id = manager.registerTargetDetectedHandler(&listener,
                                                   SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    QVERIFY(id == -1);//symbian backend does not support registerTargetDetectedHandler without QNdefFilter
}

void tst_QNearFieldManager::registerTargetDetectedHandler_filter_data()
{
    QTest::addColumn<QNdefFilter>("filter");
    QTest::addColumn<QString>("hint");

    QNdefFilter filter;

    filter.appendRecord(QNdefRecord::NfcRtd, "Sp");
    QTest::newRow("SP") << filter << "Please touch a tag with 'SP' NDef message";

    filter.clear();
    filter.setOrderMatch(true);
    filter.appendRecord(QNdefRecord::Mime, "image/png");
    filter.appendRecord<QNdefNfcTextRecord>(2, 10);
    filter.appendRecord<QNdefNfcUriRecord>(1, 1);
    QTest::newRow("Image + Multiple Text + URI") << filter << "Please touch a tag with 'Image + Multiple Text + URI' NDef message";

    filter.clear();
    filter.setOrderMatch(true);
    filter.appendRecord<QNdefNfcTextRecord>(1, 1);
    filter.appendRecord<QNdefNfcUriRecord>(1, 1);
    QTest::newRow("Text + URI") << filter << "Please touch a tag with 'Text + URI' NDef message";

    //negtive test
    filter.clear();
    filter.appendRecord<QNdefNfcUriRecord>(1, 1);
    QTest::newRow("URI") << filter << "Please touch a tag without 'URI' NDef message";

}

/*!
 Description: Unit test for NFC registerTargetDetectedHandler with a NDef filter

 TestScenario: 1. Touch a tag with random NDef message/with 'Image + Multiple Text + URI' NDef message/with 'Text + URI' NDef message

 TestExpectedResults: 1. matchedNdefMessage signal will be emitted
*/
void tst_QNearFieldManager::registerTargetDetectedHandler_filter()
{
    QFETCH(QNdefFilter, filter);
    QFETCH(QString, hint);

    QNearFieldManager manager;

    MessageListener listener;
    QSignalSpy messageSpy(&listener, SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    int id = manager.registerTargetDetectedHandler(filter, &listener,
                                                   SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    QVERIFY(id != -1);

    QNfcTestUtil::ShowMessage(hint);

    QTRY_VERIFY(!messageSpy.isEmpty());

    const QNdefMessage message = messageSpy.first().at(0).value<QNdefMessage>();

    QNearFieldTarget *target = messageSpy.first().at(1).value<QNearFieldTarget *>();

    QVERIFY(target == NULL);//symbain backend always return NULL target

    QVERIFY(manager.unregisterTargetDetectedHandler(id));
}

void tst_QNearFieldManager::registerTargetDetectedHandler_filter_negtive_data()
{
    QTest::addColumn<QNdefFilter>("filter");
    QTest::addColumn<QString>("hint");
    //negtive test
    QNdefFilter filter;

    QTest::newRow("Empty") << filter << "Please touch a tag without NDef message";

    filter.clear();
    filter.appendRecord<QNdefNfcUriRecord>(1, 1);
    QTest::newRow("URI") << filter << "Please touch a tag without 'URI' NDef message";

}

/*!
 Description: Unit test for NFC registerTargetDetectedHandler with a NDef filter

 TestScenario: 1. Touch a tag without filter expected NDef message

 TestExpectedResults: 1. matchedNdefMessage signal will NOT be emitted
*/
void tst_QNearFieldManager::registerTargetDetectedHandler_filter_negtive()
{
    QFETCH(QNdefFilter, filter);
    QFETCH(QString, hint);

    QNearFieldManager manager;

    MessageListener listener;
    QSignalSpy messageSpy(&listener, SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    int id = manager.registerTargetDetectedHandler(filter, &listener,
                                                   SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    QVERIFY(id != -1);

    QNfcTestUtil::ShowMessage(hint);

    QTRY_VERIFY(messageSpy.isEmpty());
    QVERIFY(manager.unregisterTargetDetectedHandler(id));
}

QTEST_MAIN(tst_QNearFieldManager);

#include "tst_qnearfieldmanager.moc"
<commit_msg>change test image type to gif<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used 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.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore/QString>
#include <QtTest/QtTest>
#include <QtCore/QCoreApplication>

#include "qnfctestcommon.h"
#include "qnfctestutil.h"

#include <qnearfieldmanager.h>
#include <qnearfieldtarget.h>
#include <qndefnfctextrecord.h>
#include <qndefnfcurirecord.h>
#include <qndefmessage.h>
#include <qndefrecord.h>

QTM_USE_NAMESPACE

Q_DECLARE_METATYPE(QNearFieldTarget*)
Q_DECLARE_METATYPE(QNearFieldTarget::Type)
Q_DECLARE_METATYPE(QNdefFilter)

class tst_QNearFieldManager : public QObject
{
    Q_OBJECT

public:
    tst_QNearFieldManager();

private Q_SLOTS:
    void initTestCase();
    void cleanupTestCase();
    void targetDetected();
    void targetDetected_data();
    void unregisterTargetDetectedHandler();
    void registerTargetDetectedHandler();
    void registerTargetDetectedHandler_filter_data();
    void registerTargetDetectedHandler_filter();
    void registerTargetDetectedHandler_filter_negtive();
    void registerTargetDetectedHandler_filter_negtive_data();
};

tst_QNearFieldManager::tst_QNearFieldManager()
{
    qRegisterMetaType<QNdefMessage>("QNdefMessage");
    qRegisterMetaType<QNearFieldTarget *>("QNearFieldTarget*");
}

void tst_QNearFieldManager::initTestCase()
{
    qRegisterMetaType<QNearFieldTarget *>("QNearFieldTarget *");
}

void tst_QNearFieldManager::cleanupTestCase()
{
}

/*!
 Description: Unit test for NFC target detected and lost

 TestScenario: 1. Touch and remove llcp device/Type1/Type2/Type3/Type4 tag one by one

 TestExpectedResults: 1. llcp device/Type1/Type2/Type3/Type4 tag detected/lost signal can be received
*/

void tst_QNearFieldManager::targetDetected()
{
    QFETCH(QNearFieldTarget::Type, type);
    QFETCH(QString, hint);

    QNearFieldManager nfcManager;

    QSignalSpy targetDetectedSpy(&nfcManager, SIGNAL(targetDetected(QNearFieldTarget*)));
    QSignalSpy targetLostSpy(&nfcManager, SIGNAL(targetLost(QNearFieldTarget*)));

    nfcManager.startTargetDetection(type);
    QNfcTestUtil::ShowMessage(hint);
    QTRY_VERIFY(!targetDetectedSpy.isEmpty());

    QNearFieldTarget *target = targetDetectedSpy.first().at(0).value<QNearFieldTarget *>();

    QSignalSpy disconnectedSpy(target, SIGNAL(disconnected()));
    QVERIFY(target);

    QVERIFY(!target->uid().isEmpty());

    if (type != QNearFieldTarget::AnyTarget)
    {
        QCOMPARE(target->type(), type);
    }

    QNfcTestUtil::ShowMessage("please remove the target");

    QTRY_VERIFY(!targetLostSpy.isEmpty());

    QNearFieldTarget *lostTarget = targetLostSpy.first().at(0).value<QNearFieldTarget *>();

    QCOMPARE(target, lostTarget);

    QVERIFY(!disconnectedSpy.isEmpty());

    nfcManager.stopTargetDetection();
}

void tst_QNearFieldManager::targetDetected_data()
{
    QTest::addColumn<QNearFieldTarget::Type>("type");
    QTest::addColumn<QString>("hint");
    QTest::newRow("llcp device") << QNearFieldTarget::AnyTarget << "Please touch llcp device";
    QTest::newRow("NfcTagType1") << QNearFieldTarget::NfcTagType1 << "Please touch tag type1";
    QTest::newRow("NfcTagType2") << QNearFieldTarget::NfcTagType1 << "Please touch tag type2";
    QTest::newRow("NfcTagType3") << QNearFieldTarget::NfcTagType1 << "Please touch tag type3";
    QTest::newRow("NfcTagType4") << QNearFieldTarget::NfcTagType1 << "Please touch tag type4";
}

/*!
 Description: Unit test for NFC unregisterTargetDetectedHandler function

 TestScenario: 1.

 TestExpectedResults: 1. return false
*/

void tst_QNearFieldManager::unregisterTargetDetectedHandler()
{
    QNearFieldManager manager;

    QVERIFY(!manager.unregisterTargetDetectedHandler(-1));
    QVERIFY(!manager.unregisterTargetDetectedHandler(0));
}

class MessageListener : public QObject
{
    Q_OBJECT

signals:
    void matchedNdefMessage(const QNdefMessage &message, QNearFieldTarget *target);
};

/*!
 Description: Unit test for NFC registerTargetDetectedHandler function

 TestScenario: 1. Symbian backend does not support registerTargetDetectedHandler without a QNdefFilter

 TestExpectedResults: 1. return -1
*/
void tst_QNearFieldManager::registerTargetDetectedHandler()
{
    QNearFieldManager manager;

    MessageListener listener;
    QSignalSpy messageSpy(&listener, SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    int id = manager.registerTargetDetectedHandler(&listener,
                                                   SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    QVERIFY(id == -1);//symbian backend does not support registerTargetDetectedHandler without QNdefFilter
}

void tst_QNearFieldManager::registerTargetDetectedHandler_filter_data()
{
    QTest::addColumn<QNdefFilter>("filter");
    QTest::addColumn<QString>("hint");

    QNdefFilter filter;

    filter.appendRecord(QNdefRecord::NfcRtd, "Sp");
    QTest::newRow("SP") << filter << "Please touch a tag with 'SP' NDef message";

    filter.clear();
    filter.setOrderMatch(true);
    filter.appendRecord(QNdefRecord::Mime, "image/gif");
    filter.appendRecord<QNdefNfcTextRecord>(2, 10);
    filter.appendRecord<QNdefNfcUriRecord>(1, 1);
    QTest::newRow("Image + Multiple Text + URI") << filter << "Please touch a tag with 'Image + Multiple Text + URI' NDef message";

    filter.clear();
    filter.setOrderMatch(true);
    filter.appendRecord<QNdefNfcTextRecord>(1, 1);
    filter.appendRecord<QNdefNfcUriRecord>(1, 1);
    QTest::newRow("Text + URI") << filter << "Please touch a tag with 'Text + URI' NDef message";

    //negtive test
    filter.clear();
    filter.appendRecord<QNdefNfcUriRecord>(1, 1);
    QTest::newRow("URI") << filter << "Please touch a tag without 'URI' NDef message";

}

/*!
 Description: Unit test for NFC registerTargetDetectedHandler with a NDef filter

 TestScenario: 1. Touch a tag with random NDef message/with 'Image + Multiple Text + URI' NDef message/with 'Text + URI' NDef message

 TestExpectedResults: 1. matchedNdefMessage signal will be emitted
*/
void tst_QNearFieldManager::registerTargetDetectedHandler_filter()
{
    QFETCH(QNdefFilter, filter);
    QFETCH(QString, hint);

    QNearFieldManager manager;

    MessageListener listener;
    QSignalSpy messageSpy(&listener, SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    int id = manager.registerTargetDetectedHandler(filter, &listener,
                                                   SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    QVERIFY(id != -1);

    QNfcTestUtil::ShowMessage(hint);

    QTRY_VERIFY(!messageSpy.isEmpty());

    const QNdefMessage message = messageSpy.first().at(0).value<QNdefMessage>();

    QNearFieldTarget *target = messageSpy.first().at(1).value<QNearFieldTarget *>();

    QVERIFY(target == NULL);//symbain backend always return NULL target

    QVERIFY(manager.unregisterTargetDetectedHandler(id));
}

void tst_QNearFieldManager::registerTargetDetectedHandler_filter_negtive_data()
{
    QTest::addColumn<QNdefFilter>("filter");
    QTest::addColumn<QString>("hint");
    //negtive test
    QNdefFilter filter;

    QTest::newRow("Empty") << filter << "Please touch a tag without NDef message";

    filter.clear();
    filter.appendRecord<QNdefNfcUriRecord>(1, 1);
    QTest::newRow("URI") << filter << "Please touch a tag without 'URI' NDef message";

}

/*!
 Description: Unit test for NFC registerTargetDetectedHandler with a NDef filter

 TestScenario: 1. Touch a tag without filter expected NDef message

 TestExpectedResults: 1. matchedNdefMessage signal will NOT be emitted
*/
void tst_QNearFieldManager::registerTargetDetectedHandler_filter_negtive()
{
    QFETCH(QNdefFilter, filter);
    QFETCH(QString, hint);

    QNearFieldManager manager;

    MessageListener listener;
    QSignalSpy messageSpy(&listener, SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    int id = manager.registerTargetDetectedHandler(filter, &listener,
                                                   SIGNAL(matchedNdefMessage(QNdefMessage,QNearFieldTarget*)));

    QVERIFY(id != -1);

    QNfcTestUtil::ShowMessage(hint);

    QTRY_VERIFY(messageSpy.isEmpty());
    QVERIFY(manager.unregisterTargetDetectedHandler(id));
}

QTEST_MAIN(tst_QNearFieldManager);

#include "tst_qnearfieldmanager.moc"
<|endoftext|>


<commit_before>// Petter Strandmark 2012.

#include <cstring>
#include <iostream>
#include <limits>
#include <memory>
#include <random>
#include <stdexcept>

#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#include <Eigen/Sparse>

#include <spii/spii.h>
#include <spii/solver.h>

namespace spii {

void Solver::solve_newton(const Function& function,
                   SolverResults* results) const
{
	double global_start_time = wall_time();

	// Random number engine for random pertubation.
	std::mt19937 prng(unsigned(1));
	std::uniform_real_distribution<double> uniform11(-1.0, 1.0);
	auto rand11 = std::bind(uniform11, prng);

	// Dimension of problem.
	size_t n = function.get_number_of_scalars();

	// Determine whether to use sparse representation
	// and matrix factorization.
	bool use_sparsity;
	if (this->sparsity_mode == DENSE) {
		use_sparsity = false;
	}
	else if (this->sparsity_mode == SPARSE) {
		use_sparsity = true;
	}
	else {
		if (n <= 50) {
			use_sparsity = false;
		}
		else {
			use_sparsity = true;
		}
	}

	// Current point, gradient and Hessian.
	double fval   = std::numeric_limits<double>::quiet_NaN();;
	double fprev  = std::numeric_limits<double>::quiet_NaN();
	double normg0 = std::numeric_limits<double>::quiet_NaN();
	double normg  = std::numeric_limits<double>::quiet_NaN();
	double normdx = std::numeric_limits<double>::quiet_NaN();

	Eigen::VectorXd x, g;
	Eigen::MatrixXd H;
	Eigen::SparseMatrix<double> sparse_H;
	if (use_sparsity) {
		// Create sparsity pattern for H.
		function.create_sparse_hessian(&sparse_H);
		if (this->log_function) {
			double nnz = double(sparse_H.nonZeros()) / double(n * n);
			char str[1024];
			std::sprintf(str, "H is %dx%d with %d (%.5f%%) non-zeroes.",
				sparse_H.rows(), sparse_H.cols(), sparse_H.nonZeros(), 100.0 * nnz);
			this->log_function(str);
		}
	}

	// Copy the user state to the current point.
	function.copy_user_to_global(&x);
	Eigen::VectorXd x2(n);

	// p will store the search direction.
	Eigen::VectorXd p(function.get_number_of_scalars());

	// Dense and sparse Cholesky factorizers.
	typedef Eigen::LLT<Eigen::MatrixXd> LLT;
	typedef Eigen::SimplicialLLT<Eigen::SparseMatrix<double> > SparseLLT;
	std::unique_ptr<LLT> factorization;
	std::unique_ptr<SparseLLT> sparse_factorization;
	if (!use_sparsity) {
		factorization.reset(new LLT(n));
	}
	else {
		sparse_factorization.reset(new SparseLLT);
		// The sparsity pattern of H is always the same. Therefore, it is enough
		// to analyze it once.
		sparse_factorization->analyzePattern(sparse_H);
	}

	FactorizationCache factorization_cache(n);

	//
	// START MAIN ITERATION
	//
	results->startup_time   = wall_time() - global_start_time;
	results->exit_condition = SolverResults::INTERNAL_ERROR;
	int iter = 0;
	while (true) {

		int log_interval = 1;
		if (iter > 30) {
			log_interval = 10;
		}
		if (iter > 200) {
			log_interval = 100;
		}
		if (iter > 2000) {
			log_interval = 1000;
		}

		//
		// Evaluate function and derivatives.
		//
		double start_time = wall_time();
		if (use_sparsity) {
			fval = function.evaluate(x, &g, &sparse_H);
		}
		else {
			fval = function.evaluate(x, &g, &H);
		}

		normg = std::max(g.maxCoeff(), -g.minCoeff());
		if (iter == 0) {
			normg0 = normg;
		}

		// Check for NaN.
		if (normg != normg) {
			results->exit_condition = SolverResults::FUNCTION_NAN;
			break;
		}

		results->function_evaluation_time += wall_time() - start_time;

		//
		// Test stopping criteriea
		//
		start_time = wall_time();
		if (this->check_exit_conditions(fval, fprev, normg,
			                            normg0, x.norm(), normdx,
			                            true, results)) {
			break;
		}
		if (iter >= this->maximum_iterations) {
			results->exit_condition = SolverResults::NO_CONVERGENCE;
			break;
		}
		results->stopping_criteria_time += wall_time() - start_time;

		int factorizations = 0;
		double tau = 0;
		double mindiag = 0;

		if (use_sparsity || this->factorization_method == ITERATIVE) {
			//
			// Attempt repeated Cholesky factorization until the Hessian
			// becomes positive semidefinite.
			//
			//start_time = wall_time();
			double beta = 1.0;

			Eigen::VectorXd dH;
			if (use_sparsity) {
				dH = sparse_H.diagonal();
			}
			else {
				dH = H.diagonal();
			}
			mindiag = dH.minCoeff();

			if (mindiag > 0) {
				tau = 0;
			}
			else {
				tau = -mindiag + beta;
			}
			while (true) {
				// Add tau*I to the Hessian.
				if (tau > 0) {
					for (size_t i = 0; i < n; ++i) {
						if (use_sparsity) {
							int ii = static_cast<int>(i);
							sparse_H.coeffRef(ii, ii) = dH(i) + tau;
						}
						else {
							H(i, i) = dH(i) + tau;
						}
					}
				}
				// Attempt Cholesky factorization.
				bool success;
				if (use_sparsity) {
					sparse_factorization->factorize(sparse_H);
					success = sparse_factorization->info() == Eigen::Success;
				}
				else {
					factorization->compute(H);
					success = factorization->info() == Eigen::Success;
				}
				factorizations++;
				// Check for success.
				if (success) {
					break;
				}
				tau = std::max(2*tau, beta);

				if (factorizations > 100) {
					throw std::runtime_error("Solver::solve: factorization failed.");
				}
			}

			results->matrix_factorization_time += wall_time() - start_time;

			//
			// Solve linear system to obtain search direction.
			//
			start_time = wall_time();

			if (use_sparsity) {
				p = sparse_factorization->solve(-g);
			}
			else {
				p = factorization->solve(-g);
			}

			results->linear_solver_time += wall_time() - start_time;
		}
		else {
			// Performs a BKP block diagonal factorization, modifies it, and
			// solvers the linear system.
			this->BKP_dense(H, g, factorization_cache, &p, results);
			factorizations = 1;
		}

		//
		// Perform line search.
		//
		start_time = wall_time();
		double start_alpha = 1.0;
		double alpha = this->perform_linesearch(function, x, fval, g, p, &x2,
		                                        start_alpha);

		if (alpha <= 1e-15) {

			// Attempt a simple steepest descent instead.
			p = -g;
			alpha = this->perform_linesearch(function, x, fval, g, p, &x2,
			                                 1.0);
			if (alpha <= 0) {

				if (this->log_function) {
					this->log_function("Steepest descent step failed. Numerical problems?");
				}

				// This happens in really rare cases with numerical problems or
				// incorrectly defined objective functions. In the latter case,
				// there is not much to do. In the former case, randomly perturbing
				// x has been effective.
				for (size_t i = 0; i < n; ++i) {
					x[i] = x[i] + 1e-6 * rand11() * x[i];
				}

				alpha = 0;
			}
		}

		// Record length of this step.
		normdx = alpha * p.norm();
		// Update current point.
		x = x + alpha * p;

		results->backtracking_time += wall_time() - start_time;

		//
		// Log the results of this iteration.
		//
		start_time = wall_time();

		if (this->log_function && iter % log_interval == 0) {
			char str[1024];
			if (use_sparsity) {
				if (iter == 0) {
					this->log_function("Itr      f       max|g_i|   alpha    fac    tau   min(H_ii)");
				}
				std::sprintf(str, "%4d %+10.3e %9.3e %9.3e %3d   %.1e %+.2e",
					iter, fval, normg, alpha, factorizations, tau, mindiag);
			}
			else {
				double detH = H.determinant();
				double normH = H.norm();

				if (iter == 0) {
					this->log_function("Itr      f       max|g_i|   ||H||     det(H)     alpha    fac");
				}
				std::sprintf(str, "%4d %+10.3e %9.3e %9.3e %+10.3e %9.3e %3d",
					iter, fval, normg, normH, detH, alpha, factorizations);
			}
			this->log_function(str);
		}
		results->log_time += wall_time() - start_time;

		fprev = fval;
		iter++;
	}

	function.copy_global_to_user(x);
	results->total_time = wall_time() - global_start_time;

	if (this->log_function) {
		char str[1024];
		std::sprintf(str, " end %+.3e %.3e", fval, normg);
		this->log_function(str);
	}
}

}  // namespace spii
<commit_msg>Log formatting<commit_after>// Petter Strandmark 2012.

#include <cstring>
#include <iostream>
#include <limits>
#include <memory>
#include <random>
#include <stdexcept>

#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#include <Eigen/Sparse>

#include <spii/spii.h>
#include <spii/solver.h>

namespace spii {

void Solver::solve_newton(const Function& function,
                   SolverResults* results) const
{
	double global_start_time = wall_time();

	// Random number engine for random pertubation.
	std::mt19937 prng(unsigned(1));
	std::uniform_real_distribution<double> uniform11(-1.0, 1.0);
	auto rand11 = std::bind(uniform11, prng);

	// Dimension of problem.
	size_t n = function.get_number_of_scalars();

	// Determine whether to use sparse representation
	// and matrix factorization.
	bool use_sparsity;
	if (this->sparsity_mode == DENSE) {
		use_sparsity = false;
	}
	else if (this->sparsity_mode == SPARSE) {
		use_sparsity = true;
	}
	else {
		if (n <= 50) {
			use_sparsity = false;
		}
		else {
			use_sparsity = true;
		}
	}

	// Current point, gradient and Hessian.
	double fval   = std::numeric_limits<double>::quiet_NaN();;
	double fprev  = std::numeric_limits<double>::quiet_NaN();
	double normg0 = std::numeric_limits<double>::quiet_NaN();
	double normg  = std::numeric_limits<double>::quiet_NaN();
	double normdx = std::numeric_limits<double>::quiet_NaN();

	Eigen::VectorXd x, g;
	Eigen::MatrixXd H;
	Eigen::SparseMatrix<double> sparse_H;
	if (use_sparsity) {
		// Create sparsity pattern for H.
		function.create_sparse_hessian(&sparse_H);
		if (this->log_function) {
			double nnz = double(sparse_H.nonZeros()) / double(n * n);
			char str[1024];
			std::sprintf(str, "H is %dx%d with %d (%.5f%%) non-zeroes.",
				sparse_H.rows(), sparse_H.cols(), sparse_H.nonZeros(), 100.0 * nnz);
			this->log_function(str);
		}
	}

	// Copy the user state to the current point.
	function.copy_user_to_global(&x);
	Eigen::VectorXd x2(n);

	// p will store the search direction.
	Eigen::VectorXd p(function.get_number_of_scalars());

	// Dense and sparse Cholesky factorizers.
	typedef Eigen::LLT<Eigen::MatrixXd> LLT;
	typedef Eigen::SimplicialLLT<Eigen::SparseMatrix<double> > SparseLLT;
	std::unique_ptr<LLT> factorization;
	std::unique_ptr<SparseLLT> sparse_factorization;
	if (!use_sparsity) {
		factorization.reset(new LLT(n));
	}
	else {
		sparse_factorization.reset(new SparseLLT);
		// The sparsity pattern of H is always the same. Therefore, it is enough
		// to analyze it once.
		sparse_factorization->analyzePattern(sparse_H);
	}

	FactorizationCache factorization_cache(n);

	//
	// START MAIN ITERATION
	//
	results->startup_time   = wall_time() - global_start_time;
	results->exit_condition = SolverResults::INTERNAL_ERROR;
	int iter = 0;
	while (true) {

		int log_interval = 1;
		if (iter > 30) {
			log_interval = 10;
		}
		if (iter > 200) {
			log_interval = 100;
		}
		if (iter > 2000) {
			log_interval = 1000;
		}

		//
		// Evaluate function and derivatives.
		//
		double start_time = wall_time();
		if (use_sparsity) {
			fval = function.evaluate(x, &g, &sparse_H);
		}
		else {
			fval = function.evaluate(x, &g, &H);
		}

		normg = std::max(g.maxCoeff(), -g.minCoeff());
		if (iter == 0) {
			normg0 = normg;
		}

		// Check for NaN.
		if (normg != normg) {
			results->exit_condition = SolverResults::FUNCTION_NAN;
			break;
		}

		results->function_evaluation_time += wall_time() - start_time;

		//
		// Test stopping criteriea
		//
		start_time = wall_time();
		if (this->check_exit_conditions(fval, fprev, normg,
			                            normg0, x.norm(), normdx,
			                            true, results)) {
			break;
		}
		if (iter >= this->maximum_iterations) {
			results->exit_condition = SolverResults::NO_CONVERGENCE;
			break;
		}
		results->stopping_criteria_time += wall_time() - start_time;

		int factorizations = 0;
		double tau = 0;
		double mindiag = 0;

		if (use_sparsity || this->factorization_method == ITERATIVE) {
			//
			// Attempt repeated Cholesky factorization until the Hessian
			// becomes positive semidefinite.
			//
			//start_time = wall_time();
			double beta = 1.0;

			Eigen::VectorXd dH;
			if (use_sparsity) {
				dH = sparse_H.diagonal();
			}
			else {
				dH = H.diagonal();
			}
			mindiag = dH.minCoeff();

			if (mindiag > 0) {
				tau = 0;
			}
			else {
				tau = -mindiag + beta;
			}
			while (true) {
				// Add tau*I to the Hessian.
				if (tau > 0) {
					for (size_t i = 0; i < n; ++i) {
						if (use_sparsity) {
							int ii = static_cast<int>(i);
							sparse_H.coeffRef(ii, ii) = dH(i) + tau;
						}
						else {
							H(i, i) = dH(i) + tau;
						}
					}
				}
				// Attempt Cholesky factorization.
				bool success;
				if (use_sparsity) {
					sparse_factorization->factorize(sparse_H);
					success = sparse_factorization->info() == Eigen::Success;
				}
				else {
					factorization->compute(H);
					success = factorization->info() == Eigen::Success;
				}
				factorizations++;
				// Check for success.
				if (success) {
					break;
				}
				tau = std::max(2*tau, beta);

				if (factorizations > 100) {
					throw std::runtime_error("Solver::solve: factorization failed.");
				}
			}

			results->matrix_factorization_time += wall_time() - start_time;

			//
			// Solve linear system to obtain search direction.
			//
			start_time = wall_time();

			if (use_sparsity) {
				p = sparse_factorization->solve(-g);
			}
			else {
				p = factorization->solve(-g);
			}

			results->linear_solver_time += wall_time() - start_time;
		}
		else {
			// Performs a BKP block diagonal factorization, modifies it, and
			// solvers the linear system.
			this->BKP_dense(H, g, factorization_cache, &p, results);
			factorizations = 1;
		}

		//
		// Perform line search.
		//
		start_time = wall_time();
		double start_alpha = 1.0;
		double alpha = this->perform_linesearch(function, x, fval, g, p, &x2,
		                                        start_alpha);

		if (alpha <= 1e-15) {

			// Attempt a simple steepest descent instead.
			p = -g;
			alpha = this->perform_linesearch(function, x, fval, g, p, &x2,
			                                 1.0);
			if (alpha <= 0) {

				if (this->log_function) {
					this->log_function("Steepest descent step failed. Numerical problems?");
				}

				// This happens in really rare cases with numerical problems or
				// incorrectly defined objective functions. In the latter case,
				// there is not much to do. In the former case, randomly perturbing
				// x has been effective.
				for (size_t i = 0; i < n; ++i) {
					x[i] = x[i] + 1e-6 * rand11() * x[i];
				}

				alpha = 0;
			}
		}

		// Record length of this step.
		normdx = alpha * p.norm();
		// Update current point.
		x = x + alpha * p;

		results->backtracking_time += wall_time() - start_time;

		//
		// Log the results of this iteration.
		//
		start_time = wall_time();

		if (this->log_function && iter % log_interval == 0) {
			char str[1024];
			if (use_sparsity) {
				if (iter == 0) {
					this->log_function("Itr        f        max|g_i|   alpha    fac    tau   min(H_ii)");
				}
				std::sprintf(str, "%4d %+10.6e %9.3e %9.3e %3d   %.1e %+.2e",
					iter, fval, normg, alpha, factorizations, tau, mindiag);
			}
			else {
				double detH = H.determinant();
				double normH = H.norm();

				if (iter == 0) {
					this->log_function("Itr        f        max|g_i|   ||H||     det(H)     alpha    fac");
				}
				std::sprintf(str, "%4d %+10.6e %9.3e %9.3e %+10.3e %9.3e %3d",
					iter, fval, normg, normH, detH, alpha, factorizations);
			}
			this->log_function(str);
		}
		results->log_time += wall_time() - start_time;

		fprev = fval;
		iter++;
	}

	function.copy_global_to_user(x);
	results->total_time = wall_time() - global_start_time;

	if (this->log_function) {
		char str[1024];
		std::sprintf(str, " end %+10.6e %.3e", fval, normg);
		this->log_function(str);
	}
}

}  // namespace spii
<|endoftext|>


<commit_before>/*
 * D-Bus AT-SPI, Qt Adaptor
 *
 * Copyright 2008-2011 Nokia Corporation and/or its subsidiary(-ies).
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "constant_mappings.h"

#include <qobject.h>

// FIXME the assignment of roles is quite arbitrary, at some point go through this list and sort and check that it makes sense
//  "calendar" "check menu item"  "color chooser" "column header"    "dateeditor"  "desktop icon"  "desktop frame"
//  "directory pane"  "drawing area"  "file chooser" "fontchooser"  "frame"  "glass pane"  "html container"  "icon"
//  "internal frame"  "option pane"  "password text" "radio menu item"  "root pane"  "row header"    "scroll pane"
//  "tear off menu item"  "terminal" "toggle button" "tree table"  "unknown"  "viewport" "header"  "footer"  "paragraph"
//  "ruler"    "autocomplete"  "edit bar" "embedded component"  "entry"    "caption"
//  "heading"  "page"  "section"  "redundant object"  "form"  "input method window"  "menu"

QHash <QAccessible::Role, RoleNames> qSpiRoleMapping;

static void initializeRoleMapping ()
{
    qSpiRoleMapping.insert(QAccessible::NoRole, RoleNames(ATSPI_ROLE_INVALID, "invalid", QObject::tr("invalid role")));
    qSpiRoleMapping.insert(QAccessible::TitleBar, RoleNames(ATSPI_ROLE_TEXT, "text", QObject::tr("title bar")));
    qSpiRoleMapping.insert(QAccessible::MenuBar, RoleNames(ATSPI_ROLE_MENU_BAR, "menu bar", QObject::tr("menu bar")));
    qSpiRoleMapping.insert(QAccessible::ScrollBar, RoleNames(ATSPI_ROLE_SCROLL_BAR, "scroll bar", QObject::tr("scroll bar")));
    qSpiRoleMapping.insert(QAccessible::Grip, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("grip")));
    qSpiRoleMapping.insert(QAccessible::Sound, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("sound")));
    qSpiRoleMapping.insert(QAccessible::Cursor, RoleNames(ATSPI_ROLE_ARROW, "arrow", QObject::tr("cursor")));
    qSpiRoleMapping.insert(QAccessible::Caret, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("caret")));
    qSpiRoleMapping.insert(QAccessible::AlertMessage, RoleNames(ATSPI_ROLE_ALERT, "alert", QObject::tr("alert message")));
    qSpiRoleMapping.insert(QAccessible::Window, RoleNames(ATSPI_ROLE_WINDOW, "window", QObject::tr("window")));
    qSpiRoleMapping.insert(QAccessible::Client, RoleNames(ATSPI_ROLE_FILLER, "filler", QObject::tr("filler")));
    qSpiRoleMapping.insert(QAccessible::PopupMenu, RoleNames(ATSPI_ROLE_POPUP_MENU, "popup menu", QObject::tr("popup menu")));
    qSpiRoleMapping.insert(QAccessible::MenuItem, RoleNames(ATSPI_ROLE_MENU_ITEM, "menu item", QObject::tr("menu item")));
    qSpiRoleMapping.insert(QAccessible::ToolTip, RoleNames(ATSPI_ROLE_TOOL_TIP, "tool tip", QObject::tr("tool tip")));
    qSpiRoleMapping.insert(QAccessible::Application, RoleNames(ATSPI_ROLE_APPLICATION, "application", QObject::tr("application")));
    qSpiRoleMapping.insert(QAccessible::Document, RoleNames(ATSPI_ROLE_DOCUMENT_FRAME, "document frame", QObject::tr("document")));
    qSpiRoleMapping.insert(QAccessible::Pane, RoleNames(ATSPI_ROLE_PANEL, "panel", QObject::tr("pane")));
    qSpiRoleMapping.insert(QAccessible::Chart, RoleNames(ATSPI_ROLE_CHART, "chart", QObject::tr("chart")));
    qSpiRoleMapping.insert(QAccessible::Dialog, RoleNames(ATSPI_ROLE_DIALOG, "dialog", QObject::tr("dialog")));
    qSpiRoleMapping.insert(QAccessible::Border, RoleNames(ATSPI_ROLE_FRAME, "frame", QObject::tr("border")));
    qSpiRoleMapping.insert(QAccessible::Grouping, RoleNames(ATSPI_ROLE_PANEL, "panel", QObject::tr("grouping")));
    qSpiRoleMapping.insert(QAccessible::Separator, RoleNames(ATSPI_ROLE_SEPARATOR, "separator", QObject::tr("separator")));
    qSpiRoleMapping.insert(QAccessible::ToolBar, RoleNames(ATSPI_ROLE_TOOL_BAR, "tool bar", QObject::tr("tool bar")));
    qSpiRoleMapping.insert(QAccessible::StatusBar, RoleNames(ATSPI_ROLE_STATUS_BAR, "statusbar", QObject::tr("status bar")));
    qSpiRoleMapping.insert(QAccessible::Table, RoleNames(ATSPI_ROLE_TABLE, "table", QObject::tr("table")));
    qSpiRoleMapping.insert(QAccessible::ColumnHeader, RoleNames(ATSPI_ROLE_TABLE_COLUMN_HEADER, "column header", QObject::tr("column header")));
    qSpiRoleMapping.insert(QAccessible::RowHeader, RoleNames(ATSPI_ROLE_TABLE_ROW_HEADER, "row header", QObject::tr("row header")));
    qSpiRoleMapping.insert(QAccessible::Column, RoleNames(ATSPI_ROLE_TABLE_CELL, "table cell", QObject::tr("column")));
    qSpiRoleMapping.insert(QAccessible::Row, RoleNames(ATSPI_ROLE_TABLE_CELL, "table cell", QObject::tr("row")));
    qSpiRoleMapping.insert(QAccessible::Cell, RoleNames(ATSPI_ROLE_TABLE_CELL, "table cell", QObject::tr("cell")));
    qSpiRoleMapping.insert(QAccessible::Link, RoleNames(ATSPI_ROLE_LINK, "link" , QObject::tr("link")));
    qSpiRoleMapping.insert(QAccessible::HelpBalloon, RoleNames(ATSPI_ROLE_DIALOG, "dialog", QObject::tr("help balloon")));
    qSpiRoleMapping.insert(QAccessible::Assistant, RoleNames(ATSPI_ROLE_DIALOG, "dialog", QObject::tr("assistant")));
    qSpiRoleMapping.insert(QAccessible::List, RoleNames(ATSPI_ROLE_LIST, "list", QObject::tr("list")));
    qSpiRoleMapping.insert(QAccessible::ListItem, RoleNames(ATSPI_ROLE_LIST_ITEM, "list item", QObject::tr("list item")));
    qSpiRoleMapping.insert(QAccessible::Tree, RoleNames(ATSPI_ROLE_TREE, "tree", QObject::tr("tree")));
    qSpiRoleMapping.insert(QAccessible::TreeItem, RoleNames(ATSPI_ROLE_TABLE_CELL, "tree item", QObject::tr("tree item")));
    qSpiRoleMapping.insert(QAccessible::PageTab, RoleNames(ATSPI_ROLE_PAGE_TAB, "page tab", QObject::tr("page tab")));
    qSpiRoleMapping.insert(QAccessible::PropertyPage, RoleNames(ATSPI_ROLE_PAGE_TAB, "page tab", QObject::tr("property page")));
    qSpiRoleMapping.insert(QAccessible::Indicator, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("indicator")));
    qSpiRoleMapping.insert(QAccessible::Graphic, RoleNames(ATSPI_ROLE_IMAGE, "image", QObject::tr("graphic")));
    qSpiRoleMapping.insert(QAccessible::StaticText, RoleNames(ATSPI_ROLE_LABEL, "label", QObject::tr("label")));
    qSpiRoleMapping.insert(QAccessible::EditableText, RoleNames(ATSPI_ROLE_TEXT, "text", QObject::tr("text")));
    qSpiRoleMapping.insert(QAccessible::PushButton, RoleNames(ATSPI_ROLE_PUSH_BUTTON, "push button", QObject::tr("push button")));
    qSpiRoleMapping.insert(QAccessible::CheckBox, RoleNames(ATSPI_ROLE_CHECK_BOX, "check box", QObject::tr("check box")));
    qSpiRoleMapping.insert(QAccessible::RadioButton, RoleNames(ATSPI_ROLE_RADIO_BUTTON, "radio button", QObject::tr("radio box")));
    qSpiRoleMapping.insert(QAccessible::ComboBox, RoleNames(ATSPI_ROLE_COMBO_BOX, "combo box", QObject::tr("combo box")));
    qSpiRoleMapping.insert(QAccessible::ProgressBar, RoleNames(ATSPI_ROLE_PROGRESS_BAR, "progress bar", QObject::tr("progress bar")));
    qSpiRoleMapping.insert(QAccessible::Dial, RoleNames(ATSPI_ROLE_DIAL, "accelerator label", QObject::tr("dial")));
    qSpiRoleMapping.insert(QAccessible::HotkeyField, RoleNames(ATSPI_ROLE_TEXT, "text", QObject::tr("hotkey field"))); //FIXME text?
    qSpiRoleMapping.insert(QAccessible::Slider, RoleNames(ATSPI_ROLE_SLIDER, "slider", QObject::tr("slider")));
    qSpiRoleMapping.insert(QAccessible::SpinBox, RoleNames(ATSPI_ROLE_SPIN_BUTTON, "spin button", QObject::tr("spin box")));
    qSpiRoleMapping.insert(QAccessible::Canvas, RoleNames(ATSPI_ROLE_CANVAS, "canvas", QObject::tr("canvas")));
    qSpiRoleMapping.insert(QAccessible::Animation, RoleNames(ATSPI_ROLE_ANIMATION, "animation", QObject::tr("animation")));
    qSpiRoleMapping.insert(QAccessible::Equation, RoleNames(ATSPI_ROLE_TEXT, "text", QObject::tr("equation")));
    qSpiRoleMapping.insert(QAccessible::ButtonDropDown, RoleNames(ATSPI_ROLE_PUSH_BUTTON, "push button", QObject::tr("button drop down")));
    qSpiRoleMapping.insert(QAccessible::ButtonMenu, RoleNames(ATSPI_ROLE_PUSH_BUTTON, "push button", QObject::tr("button menu")));
    qSpiRoleMapping.insert(QAccessible::ButtonDropGrid, RoleNames(ATSPI_ROLE_PUSH_BUTTON, "push button", QObject::tr("button drop grid")));
    qSpiRoleMapping.insert(QAccessible::Whitespace, RoleNames(ATSPI_ROLE_FILLER, "filler", QObject::tr("whitespace")));
    qSpiRoleMapping.insert(QAccessible::PageTabList, RoleNames(ATSPI_ROLE_PAGE_TAB_LIST, "page tab list", QObject::tr("page tab list")));
    qSpiRoleMapping.insert(QAccessible::Clock, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("clock")));
    qSpiRoleMapping.insert(QAccessible::Splitter, RoleNames(ATSPI_ROLE_SPLIT_PANE, "split pane", QObject::tr("splitter")));
    qSpiRoleMapping.insert(QAccessible::LayeredPane, RoleNames(ATSPI_ROLE_LAYERED_PANE, "layered pane", QObject::tr("layered pane")));
    qSpiRoleMapping.insert(QAccessible::UserRole, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("user role")));
}

quint64 spiStatesFromQState(QAccessible::State state)
{
    quint64 spiState = 0;

    setSpiStateBit(&spiState, ATSPI_STATE_EDITABLE);
    setSpiStateBit(&spiState, ATSPI_STATE_ENABLED);
    setSpiStateBit(&spiState, ATSPI_STATE_SHOWING);
    setSpiStateBit(&spiState, ATSPI_STATE_VISIBLE);
    setSpiStateBit(&spiState, ATSPI_STATE_SENSITIVE);

    if (state & QAccessible::Unavailable) {
        unsetSpiStateBit(&spiState, ATSPI_STATE_ENABLED);
        unsetSpiStateBit(&spiState, ATSPI_STATE_SHOWING);
        unsetSpiStateBit(&spiState, ATSPI_STATE_VISIBLE);
        unsetSpiStateBit(&spiState, ATSPI_STATE_SENSITIVE);
    }

    if (state & QAccessible::Selected)
        setSpiStateBit(&spiState, ATSPI_STATE_SELECTED);
    if (state & QAccessible::Focused)
        setSpiStateBit(&spiState, ATSPI_STATE_FOCUSED);
    if (state & QAccessible::Pressed)
        setSpiStateBit(&spiState, ATSPI_STATE_PRESSED);
    if (state & QAccessible::Checked)
        setSpiStateBit(&spiState, ATSPI_STATE_CHECKED);
    if (state & QAccessible::Mixed)
        setSpiStateBit(&spiState, ATSPI_STATE_INDETERMINATE);
    if (state & QAccessible::ReadOnly)
        unsetSpiStateBit(&spiState, ATSPI_STATE_EDITABLE);
    //        if (state & QAccessible::HotTracked)
    if (state & QAccessible::DefaultButton)
        setSpiStateBit(&spiState, ATSPI_STATE_IS_DEFAULT);
    if (state & QAccessible::Expanded)
        setSpiStateBit(&spiState, ATSPI_STATE_EXPANDED);
    if (state & QAccessible::Collapsed)
        setSpiStateBit(&spiState, ATSPI_STATE_COLLAPSED);
    if (state & QAccessible::Busy)
        setSpiStateBit(&spiState, ATSPI_STATE_BUSY);
    if ((state & QAccessible::Marqueed)
            || (state & QAccessible::Animated))
        setSpiStateBit(&spiState, ATSPI_STATE_ANIMATED);
    if ((state & QAccessible::Invisible)
            || (state & QAccessible::Offscreen))
        unsetSpiStateBit(&spiState, ATSPI_STATE_SHOWING);
    if (state & QAccessible::Sizeable)
        setSpiStateBit(&spiState, ATSPI_STATE_RESIZABLE);
    //        if (state & QAccessible::Movable)
    //        if (state & QAccessible::SelfVoicing)
    if (state & QAccessible::Focusable)
        setSpiStateBit(&spiState, ATSPI_STATE_FOCUSABLE);
    if (state & QAccessible::Selectable)
        setSpiStateBit(&spiState, ATSPI_STATE_SELECTABLE);
    //        if (state & QAccessible::Linked)
    if (state & QAccessible::Traversed)
        setSpiStateBit(&spiState, ATSPI_STATE_VISITED);
    if (state & QAccessible::MultiSelectable)
        setSpiStateBit(&spiState, ATSPI_STATE_MULTISELECTABLE);
    if (state & QAccessible::ExtSelectable)
        setSpiStateBit(&spiState, ATSPI_STATE_SELECTABLE);
    //        if (state & QAccessible::Protected)
    //        if (state & QAccessible::HasPopup)
    if (state & QAccessible::Modal)
        setSpiStateBit(&spiState, ATSPI_STATE_MODAL);

    // Not implemented in Qt
    //    if (state & QAccessible::SingleLine)
    //        setSpiStateBit(&spiState, ATSPI_STATE_SINGLE_LINE);

    return spiState;
}

QSpiUIntList spiStateSetFromSpiStates(quint64 states)
{
    uint low = states & 0xFFFFFFFF;
    uint high = (states >> 32) & 0xFFFFFFFF;

    QSpiUIntList stateList;
    stateList.append(low);
    stateList.append(high);
    return stateList;
}

void qSpiInitializeConstantMappings()
{
    initializeRoleMapping();
}
<commit_msg>When invisible we can also say not showing.<commit_after>/*
 * D-Bus AT-SPI, Qt Adaptor
 *
 * Copyright 2008-2011 Nokia Corporation and/or its subsidiary(-ies).
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "constant_mappings.h"

#include <qobject.h>

// FIXME the assignment of roles is quite arbitrary, at some point go through this list and sort and check that it makes sense
//  "calendar" "check menu item"  "color chooser" "column header"    "dateeditor"  "desktop icon"  "desktop frame"
//  "directory pane"  "drawing area"  "file chooser" "fontchooser"  "frame"  "glass pane"  "html container"  "icon"
//  "internal frame"  "option pane"  "password text" "radio menu item"  "root pane"  "row header"    "scroll pane"
//  "tear off menu item"  "terminal" "toggle button" "tree table"  "unknown"  "viewport" "header"  "footer"  "paragraph"
//  "ruler"    "autocomplete"  "edit bar" "embedded component"  "entry"    "caption"
//  "heading"  "page"  "section"  "redundant object"  "form"  "input method window"  "menu"

QHash <QAccessible::Role, RoleNames> qSpiRoleMapping;

static void initializeRoleMapping ()
{
    qSpiRoleMapping.insert(QAccessible::NoRole, RoleNames(ATSPI_ROLE_INVALID, "invalid", QObject::tr("invalid role")));
    qSpiRoleMapping.insert(QAccessible::TitleBar, RoleNames(ATSPI_ROLE_TEXT, "text", QObject::tr("title bar")));
    qSpiRoleMapping.insert(QAccessible::MenuBar, RoleNames(ATSPI_ROLE_MENU_BAR, "menu bar", QObject::tr("menu bar")));
    qSpiRoleMapping.insert(QAccessible::ScrollBar, RoleNames(ATSPI_ROLE_SCROLL_BAR, "scroll bar", QObject::tr("scroll bar")));
    qSpiRoleMapping.insert(QAccessible::Grip, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("grip")));
    qSpiRoleMapping.insert(QAccessible::Sound, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("sound")));
    qSpiRoleMapping.insert(QAccessible::Cursor, RoleNames(ATSPI_ROLE_ARROW, "arrow", QObject::tr("cursor")));
    qSpiRoleMapping.insert(QAccessible::Caret, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("caret")));
    qSpiRoleMapping.insert(QAccessible::AlertMessage, RoleNames(ATSPI_ROLE_ALERT, "alert", QObject::tr("alert message")));
    qSpiRoleMapping.insert(QAccessible::Window, RoleNames(ATSPI_ROLE_WINDOW, "window", QObject::tr("window")));
    qSpiRoleMapping.insert(QAccessible::Client, RoleNames(ATSPI_ROLE_FILLER, "filler", QObject::tr("filler")));
    qSpiRoleMapping.insert(QAccessible::PopupMenu, RoleNames(ATSPI_ROLE_POPUP_MENU, "popup menu", QObject::tr("popup menu")));
    qSpiRoleMapping.insert(QAccessible::MenuItem, RoleNames(ATSPI_ROLE_MENU_ITEM, "menu item", QObject::tr("menu item")));
    qSpiRoleMapping.insert(QAccessible::ToolTip, RoleNames(ATSPI_ROLE_TOOL_TIP, "tool tip", QObject::tr("tool tip")));
    qSpiRoleMapping.insert(QAccessible::Application, RoleNames(ATSPI_ROLE_APPLICATION, "application", QObject::tr("application")));
    qSpiRoleMapping.insert(QAccessible::Document, RoleNames(ATSPI_ROLE_DOCUMENT_FRAME, "document frame", QObject::tr("document")));
    qSpiRoleMapping.insert(QAccessible::Pane, RoleNames(ATSPI_ROLE_PANEL, "panel", QObject::tr("pane")));
    qSpiRoleMapping.insert(QAccessible::Chart, RoleNames(ATSPI_ROLE_CHART, "chart", QObject::tr("chart")));
    qSpiRoleMapping.insert(QAccessible::Dialog, RoleNames(ATSPI_ROLE_DIALOG, "dialog", QObject::tr("dialog")));
    qSpiRoleMapping.insert(QAccessible::Border, RoleNames(ATSPI_ROLE_FRAME, "frame", QObject::tr("border")));
    qSpiRoleMapping.insert(QAccessible::Grouping, RoleNames(ATSPI_ROLE_PANEL, "panel", QObject::tr("grouping")));
    qSpiRoleMapping.insert(QAccessible::Separator, RoleNames(ATSPI_ROLE_SEPARATOR, "separator", QObject::tr("separator")));
    qSpiRoleMapping.insert(QAccessible::ToolBar, RoleNames(ATSPI_ROLE_TOOL_BAR, "tool bar", QObject::tr("tool bar")));
    qSpiRoleMapping.insert(QAccessible::StatusBar, RoleNames(ATSPI_ROLE_STATUS_BAR, "statusbar", QObject::tr("status bar")));
    qSpiRoleMapping.insert(QAccessible::Table, RoleNames(ATSPI_ROLE_TABLE, "table", QObject::tr("table")));
    qSpiRoleMapping.insert(QAccessible::ColumnHeader, RoleNames(ATSPI_ROLE_TABLE_COLUMN_HEADER, "column header", QObject::tr("column header")));
    qSpiRoleMapping.insert(QAccessible::RowHeader, RoleNames(ATSPI_ROLE_TABLE_ROW_HEADER, "row header", QObject::tr("row header")));
    qSpiRoleMapping.insert(QAccessible::Column, RoleNames(ATSPI_ROLE_TABLE_CELL, "table cell", QObject::tr("column")));
    qSpiRoleMapping.insert(QAccessible::Row, RoleNames(ATSPI_ROLE_TABLE_CELL, "table cell", QObject::tr("row")));
    qSpiRoleMapping.insert(QAccessible::Cell, RoleNames(ATSPI_ROLE_TABLE_CELL, "table cell", QObject::tr("cell")));
    qSpiRoleMapping.insert(QAccessible::Link, RoleNames(ATSPI_ROLE_LINK, "link" , QObject::tr("link")));
    qSpiRoleMapping.insert(QAccessible::HelpBalloon, RoleNames(ATSPI_ROLE_DIALOG, "dialog", QObject::tr("help balloon")));
    qSpiRoleMapping.insert(QAccessible::Assistant, RoleNames(ATSPI_ROLE_DIALOG, "dialog", QObject::tr("assistant")));
    qSpiRoleMapping.insert(QAccessible::List, RoleNames(ATSPI_ROLE_LIST, "list", QObject::tr("list")));
    qSpiRoleMapping.insert(QAccessible::ListItem, RoleNames(ATSPI_ROLE_LIST_ITEM, "list item", QObject::tr("list item")));
    qSpiRoleMapping.insert(QAccessible::Tree, RoleNames(ATSPI_ROLE_TREE, "tree", QObject::tr("tree")));
    qSpiRoleMapping.insert(QAccessible::TreeItem, RoleNames(ATSPI_ROLE_TABLE_CELL, "tree item", QObject::tr("tree item")));
    qSpiRoleMapping.insert(QAccessible::PageTab, RoleNames(ATSPI_ROLE_PAGE_TAB, "page tab", QObject::tr("page tab")));
    qSpiRoleMapping.insert(QAccessible::PropertyPage, RoleNames(ATSPI_ROLE_PAGE_TAB, "page tab", QObject::tr("property page")));
    qSpiRoleMapping.insert(QAccessible::Indicator, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("indicator")));
    qSpiRoleMapping.insert(QAccessible::Graphic, RoleNames(ATSPI_ROLE_IMAGE, "image", QObject::tr("graphic")));
    qSpiRoleMapping.insert(QAccessible::StaticText, RoleNames(ATSPI_ROLE_LABEL, "label", QObject::tr("label")));
    qSpiRoleMapping.insert(QAccessible::EditableText, RoleNames(ATSPI_ROLE_TEXT, "text", QObject::tr("text")));
    qSpiRoleMapping.insert(QAccessible::PushButton, RoleNames(ATSPI_ROLE_PUSH_BUTTON, "push button", QObject::tr("push button")));
    qSpiRoleMapping.insert(QAccessible::CheckBox, RoleNames(ATSPI_ROLE_CHECK_BOX, "check box", QObject::tr("check box")));
    qSpiRoleMapping.insert(QAccessible::RadioButton, RoleNames(ATSPI_ROLE_RADIO_BUTTON, "radio button", QObject::tr("radio box")));
    qSpiRoleMapping.insert(QAccessible::ComboBox, RoleNames(ATSPI_ROLE_COMBO_BOX, "combo box", QObject::tr("combo box")));
    qSpiRoleMapping.insert(QAccessible::ProgressBar, RoleNames(ATSPI_ROLE_PROGRESS_BAR, "progress bar", QObject::tr("progress bar")));
    qSpiRoleMapping.insert(QAccessible::Dial, RoleNames(ATSPI_ROLE_DIAL, "accelerator label", QObject::tr("dial")));
    qSpiRoleMapping.insert(QAccessible::HotkeyField, RoleNames(ATSPI_ROLE_TEXT, "text", QObject::tr("hotkey field"))); //FIXME text?
    qSpiRoleMapping.insert(QAccessible::Slider, RoleNames(ATSPI_ROLE_SLIDER, "slider", QObject::tr("slider")));
    qSpiRoleMapping.insert(QAccessible::SpinBox, RoleNames(ATSPI_ROLE_SPIN_BUTTON, "spin button", QObject::tr("spin box")));
    qSpiRoleMapping.insert(QAccessible::Canvas, RoleNames(ATSPI_ROLE_CANVAS, "canvas", QObject::tr("canvas")));
    qSpiRoleMapping.insert(QAccessible::Animation, RoleNames(ATSPI_ROLE_ANIMATION, "animation", QObject::tr("animation")));
    qSpiRoleMapping.insert(QAccessible::Equation, RoleNames(ATSPI_ROLE_TEXT, "text", QObject::tr("equation")));
    qSpiRoleMapping.insert(QAccessible::ButtonDropDown, RoleNames(ATSPI_ROLE_PUSH_BUTTON, "push button", QObject::tr("button drop down")));
    qSpiRoleMapping.insert(QAccessible::ButtonMenu, RoleNames(ATSPI_ROLE_PUSH_BUTTON, "push button", QObject::tr("button menu")));
    qSpiRoleMapping.insert(QAccessible::ButtonDropGrid, RoleNames(ATSPI_ROLE_PUSH_BUTTON, "push button", QObject::tr("button drop grid")));
    qSpiRoleMapping.insert(QAccessible::Whitespace, RoleNames(ATSPI_ROLE_FILLER, "filler", QObject::tr("whitespace")));
    qSpiRoleMapping.insert(QAccessible::PageTabList, RoleNames(ATSPI_ROLE_PAGE_TAB_LIST, "page tab list", QObject::tr("page tab list")));
    qSpiRoleMapping.insert(QAccessible::Clock, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("clock")));
    qSpiRoleMapping.insert(QAccessible::Splitter, RoleNames(ATSPI_ROLE_SPLIT_PANE, "split pane", QObject::tr("splitter")));
    qSpiRoleMapping.insert(QAccessible::LayeredPane, RoleNames(ATSPI_ROLE_LAYERED_PANE, "layered pane", QObject::tr("layered pane")));
    qSpiRoleMapping.insert(QAccessible::UserRole, RoleNames(ATSPI_ROLE_UNKNOWN, "unknown", QObject::tr("user role")));
}

quint64 spiStatesFromQState(QAccessible::State state)
{
    quint64 spiState = 0;

    setSpiStateBit(&spiState, ATSPI_STATE_EDITABLE);
    setSpiStateBit(&spiState, ATSPI_STATE_ENABLED);
    setSpiStateBit(&spiState, ATSPI_STATE_SHOWING);
    setSpiStateBit(&spiState, ATSPI_STATE_VISIBLE);
    setSpiStateBit(&spiState, ATSPI_STATE_SENSITIVE);

    if (state & QAccessible::Unavailable) {
        unsetSpiStateBit(&spiState, ATSPI_STATE_ENABLED);
        unsetSpiStateBit(&spiState, ATSPI_STATE_SHOWING);
        unsetSpiStateBit(&spiState, ATSPI_STATE_VISIBLE);
        unsetSpiStateBit(&spiState, ATSPI_STATE_SENSITIVE);
    }

    if (state & QAccessible::Selected)
        setSpiStateBit(&spiState, ATSPI_STATE_SELECTED);
    if (state & QAccessible::Focused)
        setSpiStateBit(&spiState, ATSPI_STATE_FOCUSED);
    if (state & QAccessible::Pressed)
        setSpiStateBit(&spiState, ATSPI_STATE_PRESSED);
    if (state & QAccessible::Checked)
        setSpiStateBit(&spiState, ATSPI_STATE_CHECKED);
    if (state & QAccessible::Mixed)
        setSpiStateBit(&spiState, ATSPI_STATE_INDETERMINATE);
    if (state & QAccessible::ReadOnly)
        unsetSpiStateBit(&spiState, ATSPI_STATE_EDITABLE);
    //        if (state & QAccessible::HotTracked)
    if (state & QAccessible::DefaultButton)
        setSpiStateBit(&spiState, ATSPI_STATE_IS_DEFAULT);
    if (state & QAccessible::Expanded)
        setSpiStateBit(&spiState, ATSPI_STATE_EXPANDED);
    if (state & QAccessible::Collapsed)
        setSpiStateBit(&spiState, ATSPI_STATE_COLLAPSED);
    if (state & QAccessible::Busy)
        setSpiStateBit(&spiState, ATSPI_STATE_BUSY);
    if ((state & QAccessible::Marqueed)
            || (state & QAccessible::Animated))
        setSpiStateBit(&spiState, ATSPI_STATE_ANIMATED);
    if ((state & QAccessible::Invisible)
            || (state & QAccessible::Offscreen)) {
        unsetSpiStateBit(&spiState, ATSPI_STATE_SHOWING);
        unsetSpiStateBit(&spiState, ATSPI_STATE_VISIBLE);
    }
    if (state & QAccessible::Sizeable)
        setSpiStateBit(&spiState, ATSPI_STATE_RESIZABLE);
    //        if (state & QAccessible::Movable)
    //        if (state & QAccessible::SelfVoicing)
    if (state & QAccessible::Focusable)
        setSpiStateBit(&spiState, ATSPI_STATE_FOCUSABLE);
    if (state & QAccessible::Selectable)
        setSpiStateBit(&spiState, ATSPI_STATE_SELECTABLE);
    //        if (state & QAccessible::Linked)
    if (state & QAccessible::Traversed)
        setSpiStateBit(&spiState, ATSPI_STATE_VISITED);
    if (state & QAccessible::MultiSelectable)
        setSpiStateBit(&spiState, ATSPI_STATE_MULTISELECTABLE);
    if (state & QAccessible::ExtSelectable)
        setSpiStateBit(&spiState, ATSPI_STATE_SELECTABLE);
    //        if (state & QAccessible::Protected)
    //        if (state & QAccessible::HasPopup)
    if (state & QAccessible::Modal)
        setSpiStateBit(&spiState, ATSPI_STATE_MODAL);

    // Not implemented in Qt
    //    if (state & QAccessible::SingleLine)
    //        setSpiStateBit(&spiState, ATSPI_STATE_SINGLE_LINE);

    return spiState;
}

QSpiUIntList spiStateSetFromSpiStates(quint64 states)
{
    uint low = states & 0xFFFFFFFF;
    uint high = (states >> 32) & 0xFFFFFFFF;

    QSpiUIntList stateList;
    stateList.append(low);
    stateList.append(high);
    return stateList;
}

void qSpiInitializeConstantMappings()
{
    initializeRoleMapping();
}
<|endoftext|>