<commit_before>/*************************************************************************
 *
 *  $RCSfile: SwAppletImpl.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-08-12 11:58:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SW_APPLET_IMPL_HXX
#define _SW_APPLET_IMPL_HXX

#define SWHTML_OPTTYPE_IGNORE 0
#define SWHTML_OPTTYPE_TAG 1
#define SWHTML_OPTTYPE_PARAM 2
#define SWHTML_OPTTYPE_SIZE 3

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef _HTMLKYWD_HXX
#include <svtools/htmlkywd.hxx>
#endif
#ifndef _FRMHTML_HXX //autogen
#include <sfx2/frmhtml.hxx>
#endif
#ifndef _FRAMEOBJ_HXX //autogen
#include <sfx2/frameobj.hxx>
#endif
#ifndef _FRMHTMLW_HXX //autogen
#include <sfx2/frmhtmlw.hxx>
#endif
#ifndef _WRKWIN_HXX //autogen
#include <vcl/wrkwin.hxx>
#endif
#ifndef _SVSTOR_HXX //autogen
#include <so3/svstor.hxx>
#endif
#ifndef _APPLET_HXX //autogen
#include <so3/applet.hxx>
#endif
#ifndef _PLUGIN_HXX //autogen
#include <so3/plugin.hxx>
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif

class SfxItemSet;

extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_O_hidden, "HIDDEN" );
extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_HIDDEN_false, "FALSE" );
extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_O_archive, "ARCHIVE" );
extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_O_archives, "ARCHIVES" );
extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_O_object, "OBJECT" );

class SwApplet_Impl
{
    SvAppletObjectRef xApplet;      // das aktuelle Applet
    SvCommandList     aCommandList; // und die szugehorige Command-List
    SfxItemSet        aItemSet;
    String            sAlt;

public:
    static USHORT GetOptionType( const String& rName, BOOL bApplet );
    SwApplet_Impl( SfxItemPool& rPool, USHORT nWhich1, USHORT nWhich2 );
    SwApplet_Impl( SfxItemSet& rSet ): aItemSet ( rSet) {}
    ~SwApplet_Impl();
    void CreateApplet( const String& rCode, const String& rName,
                       BOOL bMayScript, const String& rCodeBase );
#ifdef SOLAR_JAVA
    sal_Bool CreateApplet();
    void AppendParam( const String& rName, const String& rValue );
#endif
    void FinishApplet();
    SvAppletObject* GetApplet() { return &xApplet; }
    SfxItemSet& GetItemSet() { return aItemSet; }
    const String& GetAltText() { return sAlt; }
    void          SetAltText( const String& rAlt ) {sAlt = rAlt;}
};
#endif
<commit_msg>INTEGRATION: CWS mav09 (1.2.264); FILE MERGED 2004/09/16 19:00:53 mav 1.2.264.3: RESYNC: (1.2-1.3); FILE MERGED 2004/06/18 14:07:59 mba 1.2.264.2: #i27773#: new API for Applets 2004/05/18 16:43:01 mba 1.2.264.1: RESYNC to m39<commit_after>/*************************************************************************
 *
 *  $RCSfile: SwAppletImpl.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2004-10-04 18:57:25 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SW_APPLET_IMPL_HXX
#define _SW_APPLET_IMPL_HXX

#define SWHTML_OPTTYPE_IGNORE 0
#define SWHTML_OPTTYPE_TAG 1
#define SWHTML_OPTTYPE_PARAM 2
#define SWHTML_OPTTYPE_SIZE 3

#ifndef _COM_SUN_STAR_EMBED_XEMBEDDEDOBJECT_HPP_
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#endif

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef _HTMLKYWD_HXX
#include <svtools/htmlkywd.hxx>
#endif
#ifndef _FRMHTML_HXX //autogen
#include <sfx2/frmhtml.hxx>
#endif
#ifndef _FRMHTMLW_HXX //autogen
#include <sfx2/frmhtmlw.hxx>
#endif
#ifndef _WRKWIN_HXX //autogen
#include <vcl/wrkwin.hxx>
#endif
#include <sot/storage.hxx>
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif

#include <svtools/ownlist.hxx>

class SfxItemSet;

extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_O_hidden, "HIDDEN" );
extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_HIDDEN_false, "FALSE" );
extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_O_archive, "ARCHIVE" );
extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_O_archives, "ARCHIVES" );
extern sal_Char __FAR_DATA SVTOOLS_CONSTASCII_DECL( sHTML_O_object, "OBJECT" );

class SwApplet_Impl
{
    com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > xApplet;
    SvCommandList     aCommandList; // und die szugehorige Command-List
    SfxItemSet        aItemSet;
    String            sAlt;

public:
    static USHORT GetOptionType( const String& rName, BOOL bApplet );
    SwApplet_Impl( SfxItemPool& rPool, USHORT nWhich1, USHORT nWhich2 );
    SwApplet_Impl( SfxItemSet& rSet ): aItemSet ( rSet) {}
    ~SwApplet_Impl();
    void CreateApplet( const String& rCode, const String& rName,
                       BOOL bMayScript, const String& rCodeBase );
#ifdef SOLAR_JAVA
    sal_Bool CreateApplet();
    void AppendParam( const String& rName, const String& rValue );
#endif
    void FinishApplet();
    com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > GetApplet() { return xApplet; }
    SfxItemSet& GetItemSet() { return aItemSet; }
    const String& GetAltText() { return sAlt; }
    void          SetAltText( const String& rAlt ) {sAlt = rAlt;}
};
#endif
<|endoftext|>


<commit_before>#include "Image.h"

#include "dataset/TPNode.h"
#include "render/GL10.h"
#include "render/Shader.h"
#include "render/ShaderMgr.h"
//#include "render/DynamicTexture.h"
#include "render/DynamicTexAndFont.h"
#include "render/RenderList.h"
#include "render/BlendShader.h"
#include "render/ScreenFBO.h"
#include "common/tools.h"
#include "common/Exception.h"
#include "common/Math.h"
#include "common/Config.h"
#include "common/SettingData.h"
#include "common/TodoConfig.h"

#include <fstream>
#include <easyimage.h>
#include <wx/filename.h>

namespace d2d
{

Image::Image(const uint8_t* pixel, int width, int height)
	: m_tex(pixel, width, height)
{
	ResetClippedRegion();
}

Image::~Image()
{
	ImageMgr::Instance()->RemoveItem(m_tex.GetFilepath());
}

bool Image::LoadFromFile(const std::string& filepath)
{
	if (!wxFileName::FileExists(filepath)) {
		throw Exception("Image File: %s don't exist!", filepath.c_str());
	}

#ifdef NOT_LOAD_IMAGE
	// todo
	m_clipped_region.xMin = m_clipped_region.xMax = m_clipped_region.yMin = m_clipped_region.yMax = 0;
	return true;
#endif

	m_tex.LoadFromFile(filepath);

 	if (m_tex.GetTexID() == 0)
 	{
//		assert(0);
//		m_width = m_height = 0;
 		return true;
 	}
 	else
 	{
		if (Config::Instance()->GetSettings().open_image_edge_clip)
		{
			eimage::ImageTrim trim(this);
			d2d::Rect r = trim.Trim();
			if (r.isValid()) {
				r.translate(d2d::Vector(-m_tex.GetWidth()*0.5f, -m_tex.GetHeight()*0.5f));
				m_clipped_region = r;
			}
		}
		else
		{
			ResetClippedRegion();
		}

// 		// todo
// 		DynamicTexture::Instance()->Insert(this);
		if (Config::Instance()->IsUseDTex()) {
			DynamicTexAndFont::Instance()->AddImage(this);
		}

 		return true;
 	}
}

void Image::Reload()
{
	m_tex.Reload();
	ResetClippedRegion();
}

void Image::Draw(const Matrix& mt, const Rect& r, const ISprite* spr) const
{
	////////////////////////////////////////////////////////////////////////////
	//// ԭʼ ֱӻ
 //   	ShaderMgr* shader = ShaderMgr::Instance();
 //   	shader->sprite();
 //
 //   	float tot_hw = m_width * 0.5f,
 //   		  tot_hh = m_height * 0.5f;
 //   	float txmin = (r.xMin + tot_hw) / m_width,
 //   		txmax = (r.xMax + tot_hw) / m_width,
 //   		tymin = (r.yMin + tot_hh) / m_height,
 //   		tymax = (r.yMax + tot_hh) / m_height;
 //
 // 	d2d::Vector vertices[4];
 // 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
 // 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
 // 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
 // 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);
 //
 // 	for (int i = 0; i < 4; ++i) {
 // 		scr.TransPosForRender(vertices[i]);
 // 	}
 //
 // 	float vb[16];
 // 	vb[0] = vertices[0].x;
 // 	vb[1] = vertices[0].y;
 // 	vb[2] = txmin;
 // 	vb[3] = tymin;
 // 	vb[4] = vertices[1].x;
 // 	vb[5] = vertices[1].y;
 // 	vb[6] = txmax;
 // 	vb[7] = tymin;
 // 	vb[8] = vertices[2].x;
 // 	vb[9] = vertices[2].y;
 // 	vb[10] = txmax;
 // 	vb[11] = tymax;
 // 	vb[12] = vertices[3].x;
 // 	vb[13] = vertices[3].y;
 // 	vb[14] = txmin;
 // 	vb[15] = tymax;
 //
 // 	shader->Draw(vb, m_textureID);

	//////////////////////////////////////////////////////////////////////////
//	renderlist
// 	d2d::Vector vertices[4];
// 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
// 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
// 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
// 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);
// 	for (int i = 0; i < 4; ++i) {
// 		scr.TransPosForRender(vertices[i]);
// 	}
//
// 	d2d::Vector texcoords[4];
// 	float tot_hw = m_width * 0.5f,
// 		tot_hh = m_height * 0.5f;
// 	float txmin = (r.xMin + tot_hw) / m_width,
// 		txmax = (r.xMax + tot_hw) / m_width,
// 		tymin = (r.yMin + tot_hh) / m_height,
// 		tymax = (r.yMax + tot_hh) / m_height;
// 	texcoords[0].set(txmin, tymin);
// 	texcoords[1].set(txmax, tymin);
// 	texcoords[2].set(txmax, tymax);
// 	texcoords[3].set(txmin, tymax);
//
// 	RenderList::Instance()->Insert(m_textureID, vertices, texcoords);

	//////////////////////////////////////////////////////////////////////////
	// dtex

	float px = 0, py = 0;
	if (spr) {
		px = spr->GetPerspective().x;
		py = spr->GetPerspective().y;
	}

 	d2d::Vector vertices[4];
 	vertices[0] = Math::transVector(Vector(r.xMin - px, r.yMin - py), mt);
 	vertices[1] = Math::transVector(Vector(r.xMax + px, r.yMin + py), mt);
 	vertices[2] = Math::transVector(Vector(r.xMax - px, r.yMax - py), mt);
 	vertices[3] = Math::transVector(Vector(r.xMin + px, r.yMax + py), mt);

	int texid;
	d2d::Vector texcoords[4];
	float txmin, txmax, tymin, tymax;
	DynamicTexAndFont* dt = NULL;
	const TPNode* n = NULL;
	if (Config::Instance()->IsUseDTex()) {
		dt = DynamicTexAndFont::Instance();
		n = dt->Query(m_tex.GetFilepath());
	}
 	if (n)
 	{
 		float extend = dt->GetExtend();
 		int width = dt->GetWidth();
 		int height = dt->GetHeight();
 		texid = dt->GetTextureID();
		txmin = (n->GetMinX()+extend) / width;
		txmax = (n->GetMaxX()-extend) / width;
		tymin = (n->GetMinY()+extend) / height;
		tymax = (n->GetMaxY()-extend) / height;

		if (texid != 1) {
			wxLogDebug(_T("img dt's tex = %d"), texid);
		}

 		if (n->IsRotated())
 		{
 			d2d::Vector tmp = vertices[3];
 			vertices[3] = vertices[2];
 			vertices[2] = vertices[1];
 			vertices[1] = vertices[0];
 			vertices[0] = tmp;
 		}
 	}
 	else
	{
		//wxLogDebug("Fail to insert dtex: %s", m_filepath.c_str());

		texid = m_tex.GetTexID();
		float w = m_tex.GetWidth(),
			h = m_tex.GetHeight();
		float hw = 0.5f * w,
			hh = 0.5f * h;
	 	txmin = (r.xMin + hw) / w;
	 	txmax = (r.xMax + hw) / w;
	 	tymin = (r.yMin + hh) / h;
	 	tymax = (r.yMax + hh) / h;
	}
 	texcoords[0].set(txmin, tymin);
 	texcoords[1].set(txmax, tymin);
 	texcoords[2].set(txmax, tymax);
 	texcoords[3].set(txmin, tymax);

//	RenderList::Instance()->Insert(texid, vertices, texcoords);

	ShaderMgr* mgr = ShaderMgr::Instance();
	mgr->sprite();

	if (BlendShader* blend_shader = dynamic_cast<BlendShader*>(mgr->GetSpriteShader())) {
		SpriteRenderer* rd = SpriteRenderer::Instance();
		const Camera* cam = rd->GetCamera();
		assert(cam);

		int w = ScreenFBO::Instance()->GetFBO().GetWidth(),
			h = ScreenFBO::Instance()->GetFBO().GetHeight();

		//////////////////////////////////////////////////////////////////////////

		assert(spr);
		d2d::Vector vertices_scr[4];
		d2d::Rect r = spr->GetRect();
		vertices_scr[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
		vertices_scr[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
		vertices_scr[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
		vertices_scr[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);

		d2d::Vector tex_coolds_base[4];
		for (int i = 0; i < 4; ++i) {
			tex_coolds_base[i] = cam->transPosProjectToScreen(vertices_scr[i], w, h);
			tex_coolds_base[i].y = h - 1 - tex_coolds_base[i].y;
			tex_coolds_base[i].x /= w;
			tex_coolds_base[i].y /= h;
			tex_coolds_base[i].x = std::min(std::max(0.0f, tex_coolds_base[i].x), 1.0f);
			tex_coolds_base[i].y = std::min(std::max(0.0f, tex_coolds_base[i].y), 1.0f);
		}

		//////////////////////////////////////////////////////////////////////////

//  		assert(spr);
//  		d2d::Vector vertices_scr[4];
//  		d2d::Rect r = spr->GetRect();
//  		vertices_scr[0] = Math::transVector(Vector(0.0f, 0.0f), mt);
//  		vertices_scr[1] = Math::transVector(Vector(r.xLength(), 0.0f), mt);
//  		vertices_scr[2] = Math::transVector(Vector(r.xLength(), r.yLength()), mt);
//  		vertices_scr[3] = Math::transVector(Vector(0.0f, r.yLength()), mt);
//
//  		d2d::Vector tex_coolds_base[4];
//  		for (int i = 0; i < 4; ++i) {
//  			tex_coolds_base[i] = cam->transPosProjectToScreen(vertices_scr[i], w, h);
//  			tex_coolds_base[i].x /= w;
//  			tex_coolds_base[i].y /= h;
//  			tex_coolds_base[i].x = std::min(std::max(0.0f, tex_coolds_base[i].x), 1.0f);
//  			tex_coolds_base[i].y = std::min(std::max(0.0f, tex_coolds_base[i].y), 1.0f);
//  		}

		//////////////////////////////////////////////////////////////////////////

		blend_shader->DrawBlend(vertices, texcoords, tex_coolds_base, texid);
	} else {
		mgr->Draw(vertices, texcoords, texid);
	}
}

void Image::ResetClippedRegion()
{
	m_clipped_region.xMax = m_tex.GetWidth() * 0.5f;
	m_clipped_region.xMin = -m_clipped_region.xMax;
	m_clipped_region.yMax = m_tex.GetHeight() * 0.5f;
	m_clipped_region.yMin = -m_clipped_region.yMax;
}

} // d2d<commit_msg>[FIXED] Image::LoadFromFile<commit_after>#include "Image.h"

#include "dataset/TPNode.h"
#include "render/GL10.h"
#include "render/Shader.h"
#include "render/ShaderMgr.h"
//#include "render/DynamicTexture.h"
#include "render/DynamicTexAndFont.h"
#include "render/RenderList.h"
#include "render/BlendShader.h"
#include "render/ScreenFBO.h"
#include "common/tools.h"
#include "common/Exception.h"
#include "common/Math.h"
#include "common/Config.h"
#include "common/SettingData.h"
#include "common/TodoConfig.h"

#include <fstream>
#include <easyimage.h>
#include <wx/filename.h>

namespace d2d
{

Image::Image(const uint8_t* pixel, int width, int height)
	: m_tex(pixel, width, height)
{
	ResetClippedRegion();
}

Image::~Image()
{
	ImageMgr::Instance()->RemoveItem(m_tex.GetFilepath());
}

bool Image::LoadFromFile(const std::string& filepath)
{
	if (!wxFileName::FileExists(filepath)) {
		throw Exception("Image File: %s don't exist!", filepath.c_str());
	}

#ifdef NOT_LOAD_IMAGE
	// todo
	m_clipped_region.xMin = m_clipped_region.xMax = m_clipped_region.yMin = m_clipped_region.yMax = 0;
	return true;
#endif

	m_tex.LoadFromFile(filepath);

 	if (m_tex.GetWidth() == 0 || m_tex.GetHeight() == 0)
 	{
 		return true;
 	}
 	else
 	{
		if (Config::Instance()->GetSettings().open_image_edge_clip)
		{
			eimage::ImageTrim trim(this);
			d2d::Rect r = trim.Trim();
			if (r.isValid()) {
				r.translate(d2d::Vector(-m_tex.GetWidth()*0.5f, -m_tex.GetHeight()*0.5f));
				m_clipped_region = r;
			}
		}
		else
		{
			ResetClippedRegion();
		}

// 		// todo
// 		DynamicTexture::Instance()->Insert(this);
		if (Config::Instance()->IsUseDTex()) {
			DynamicTexAndFont::Instance()->AddImage(this);
		}

 		return true;
 	}
}

void Image::Reload()
{
	m_tex.Reload();
	ResetClippedRegion();
}

void Image::Draw(const Matrix& mt, const Rect& r, const ISprite* spr) const
{
	////////////////////////////////////////////////////////////////////////////
	//// ԭʼ ֱӻ
 //   	ShaderMgr* shader = ShaderMgr::Instance();
 //   	shader->sprite();
 //
 //   	float tot_hw = m_width * 0.5f,
 //   		  tot_hh = m_height * 0.5f;
 //   	float txmin = (r.xMin + tot_hw) / m_width,
 //   		txmax = (r.xMax + tot_hw) / m_width,
 //   		tymin = (r.yMin + tot_hh) / m_height,
 //   		tymax = (r.yMax + tot_hh) / m_height;
 //
 // 	d2d::Vector vertices[4];
 // 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
 // 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
 // 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
 // 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);
 //
 // 	for (int i = 0; i < 4; ++i) {
 // 		scr.TransPosForRender(vertices[i]);
 // 	}
 //
 // 	float vb[16];
 // 	vb[0] = vertices[0].x;
 // 	vb[1] = vertices[0].y;
 // 	vb[2] = txmin;
 // 	vb[3] = tymin;
 // 	vb[4] = vertices[1].x;
 // 	vb[5] = vertices[1].y;
 // 	vb[6] = txmax;
 // 	vb[7] = tymin;
 // 	vb[8] = vertices[2].x;
 // 	vb[9] = vertices[2].y;
 // 	vb[10] = txmax;
 // 	vb[11] = tymax;
 // 	vb[12] = vertices[3].x;
 // 	vb[13] = vertices[3].y;
 // 	vb[14] = txmin;
 // 	vb[15] = tymax;
 //
 // 	shader->Draw(vb, m_textureID);

	//////////////////////////////////////////////////////////////////////////
//	renderlist
// 	d2d::Vector vertices[4];
// 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
// 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
// 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
// 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);
// 	for (int i = 0; i < 4; ++i) {
// 		scr.TransPosForRender(vertices[i]);
// 	}
//
// 	d2d::Vector texcoords[4];
// 	float tot_hw = m_width * 0.5f,
// 		tot_hh = m_height * 0.5f;
// 	float txmin = (r.xMin + tot_hw) / m_width,
// 		txmax = (r.xMax + tot_hw) / m_width,
// 		tymin = (r.yMin + tot_hh) / m_height,
// 		tymax = (r.yMax + tot_hh) / m_height;
// 	texcoords[0].set(txmin, tymin);
// 	texcoords[1].set(txmax, tymin);
// 	texcoords[2].set(txmax, tymax);
// 	texcoords[3].set(txmin, tymax);
//
// 	RenderList::Instance()->Insert(m_textureID, vertices, texcoords);

	//////////////////////////////////////////////////////////////////////////
	// dtex

	float px = 0, py = 0;
	if (spr) {
		px = spr->GetPerspective().x;
		py = spr->GetPerspective().y;
	}

 	d2d::Vector vertices[4];
 	vertices[0] = Math::transVector(Vector(r.xMin - px, r.yMin - py), mt);
 	vertices[1] = Math::transVector(Vector(r.xMax + px, r.yMin + py), mt);
 	vertices[2] = Math::transVector(Vector(r.xMax - px, r.yMax - py), mt);
 	vertices[3] = Math::transVector(Vector(r.xMin + px, r.yMax + py), mt);

	int texid;
	d2d::Vector texcoords[4];
	float txmin, txmax, tymin, tymax;
	DynamicTexAndFont* dt = NULL;
	const TPNode* n = NULL;
	if (Config::Instance()->IsUseDTex()) {
		dt = DynamicTexAndFont::Instance();
		n = dt->Query(m_tex.GetFilepath());
	}
 	if (n)
 	{
 		float extend = dt->GetExtend();
 		int width = dt->GetWidth();
 		int height = dt->GetHeight();
 		texid = dt->GetTextureID();
		txmin = (n->GetMinX()+extend) / width;
		txmax = (n->GetMaxX()-extend) / width;
		tymin = (n->GetMinY()+extend) / height;
		tymax = (n->GetMaxY()-extend) / height;

		if (texid != 1) {
			wxLogDebug(_T("img dt's tex = %d"), texid);
		}

 		if (n->IsRotated())
 		{
 			d2d::Vector tmp = vertices[3];
 			vertices[3] = vertices[2];
 			vertices[2] = vertices[1];
 			vertices[1] = vertices[0];
 			vertices[0] = tmp;
 		}
 	}
 	else
	{
		//wxLogDebug("Fail to insert dtex: %s", m_filepath.c_str());

		texid = m_tex.GetTexID();
		float w = m_tex.GetWidth(),
			h = m_tex.GetHeight();
		float hw = 0.5f * w,
			hh = 0.5f * h;
	 	txmin = (r.xMin + hw) / w;
	 	txmax = (r.xMax + hw) / w;
	 	tymin = (r.yMin + hh) / h;
	 	tymax = (r.yMax + hh) / h;
	}
 	texcoords[0].set(txmin, tymin);
 	texcoords[1].set(txmax, tymin);
 	texcoords[2].set(txmax, tymax);
 	texcoords[3].set(txmin, tymax);

//	RenderList::Instance()->Insert(texid, vertices, texcoords);

	ShaderMgr* mgr = ShaderMgr::Instance();
	mgr->sprite();

	if (BlendShader* blend_shader = dynamic_cast<BlendShader*>(mgr->GetSpriteShader())) {
		SpriteRenderer* rd = SpriteRenderer::Instance();
		const Camera* cam = rd->GetCamera();
		assert(cam);

		int w = ScreenFBO::Instance()->GetFBO().GetWidth(),
			h = ScreenFBO::Instance()->GetFBO().GetHeight();

		//////////////////////////////////////////////////////////////////////////

		assert(spr);
		d2d::Vector vertices_scr[4];
		d2d::Rect r = spr->GetRect();
		vertices_scr[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
		vertices_scr[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
		vertices_scr[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
		vertices_scr[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);

		d2d::Vector tex_coolds_base[4];
		for (int i = 0; i < 4; ++i) {
			tex_coolds_base[i] = cam->transPosProjectToScreen(vertices_scr[i], w, h);
			tex_coolds_base[i].y = h - 1 - tex_coolds_base[i].y;
			tex_coolds_base[i].x /= w;
			tex_coolds_base[i].y /= h;
			tex_coolds_base[i].x = std::min(std::max(0.0f, tex_coolds_base[i].x), 1.0f);
			tex_coolds_base[i].y = std::min(std::max(0.0f, tex_coolds_base[i].y), 1.0f);
		}

		//////////////////////////////////////////////////////////////////////////

//  		assert(spr);
//  		d2d::Vector vertices_scr[4];
//  		d2d::Rect r = spr->GetRect();
//  		vertices_scr[0] = Math::transVector(Vector(0.0f, 0.0f), mt);
//  		vertices_scr[1] = Math::transVector(Vector(r.xLength(), 0.0f), mt);
//  		vertices_scr[2] = Math::transVector(Vector(r.xLength(), r.yLength()), mt);
//  		vertices_scr[3] = Math::transVector(Vector(0.0f, r.yLength()), mt);
//
//  		d2d::Vector tex_coolds_base[4];
//  		for (int i = 0; i < 4; ++i) {
//  			tex_coolds_base[i] = cam->transPosProjectToScreen(vertices_scr[i], w, h);
//  			tex_coolds_base[i].x /= w;
//  			tex_coolds_base[i].y /= h;
//  			tex_coolds_base[i].x = std::min(std::max(0.0f, tex_coolds_base[i].x), 1.0f);
//  			tex_coolds_base[i].y = std::min(std::max(0.0f, tex_coolds_base[i].y), 1.0f);
//  		}

		//////////////////////////////////////////////////////////////////////////

		blend_shader->DrawBlend(vertices, texcoords, tex_coolds_base, texid);
	} else {
		mgr->Draw(vertices, texcoords, texid);
	}
}

void Image::ResetClippedRegion()
{
	m_clipped_region.xMax = m_tex.GetWidth() * 0.5f;
	m_clipped_region.xMin = -m_clipped_region.xMax;
	m_clipped_region.yMax = m_tex.GetHeight() * 0.5f;
	m_clipped_region.yMin = -m_clipped_region.yMax;
}

} // d2d<|endoftext|>


<commit_before>/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "NFCEEPROM.h"
#include "ndef/ndef.h"

using namespace mbed;
using namespace mbed::nfc;

NFCEEPROM::NFCEEPROM(NFCEEPROMDriver *driver, events::EventQueue *queue, const Span<uint8_t> &ndef_buffer) : NFCTarget(ndef_buffer),
    _delegate(NULL), _driver(driver), _event_queue(queue), _initialized(false), _current_op(nfc_eeprom_idle), _ndef_buffer_read_sz(0), _eeprom_address(0),
    _operation_result(NFC_ERR_UNKNOWN), _ndef_buffer_reader{nullptr, 0, nullptr}
{
    _driver->set_delegate(this);
    _driver->set_event_queue(queue);
}

nfc_err_t NFCEEPROM::initialize()
{
    MBED_ASSERT(_initialized == false); // Initialize should only be called once

    // Initialize driver
    _driver->reset();
    _initialized = true;
    return NFC_OK;
}

void NFCEEPROM::set_delegate(NFCEEPROM::Delegate *delegate)
{
    _delegate = delegate;
}

void NFCEEPROM::write_ndef_message()
{
    MBED_ASSERT(_initialized == true);
    if (_current_op != nfc_eeprom_idle) {
        if (_delegate != NULL) {
            _delegate->on_ndef_message_written(NFC_ERR_BUSY);
        }
        return;
    }

    // First update NDEF message if required
    ndef_msg_encode(ndef_message());

    _current_op = nfc_eeprom_write_start_session;

    // Retrieve reader
    ac_buffer_dup(&_ndef_buffer_reader, ac_buffer_builder_buffer(ndef_msg_buffer_builder(ndef_message())));

    // Check that NDEF message is not too big
    if (ac_buffer_reader_readable(&_ndef_buffer_reader) > _driver->read_max_size()) {
        handle_error(NFC_ERR_BUFFER_TOO_SMALL);
        return;
    }

    // Reset EEPROM address
    _eeprom_address = 0;
    // Go through the steps!
    _driver->start_session();

    // 1 - Start session
    // 2 - Write bytes (can be repeated)
    // 3 - Set NDEF message size
    // 4 - End session
}

void NFCEEPROM::read_ndef_message()
{
    MBED_ASSERT(_initialized == true);
    if (_current_op != nfc_eeprom_idle) {
        if (_delegate != NULL) {
            _delegate->on_ndef_message_written(NFC_ERR_BUSY);
        }
        return;
    }
    _current_op = nfc_eeprom_read_start_session;

    // Reset EEPROM address
    _eeprom_address = 0;

    // Go through the steps!
    _driver->start_session();

    // 1 - Start session
    // 2 - Get NDEF message size
    // 3 - Read bytes (can be repeated)
    // 4 - End session
}

void NFCEEPROM::erase_ndef_message()
{
    // We don't want to take any risks, so erase the whole address space
    // And set the message size to 0

    MBED_ASSERT(_initialized == true);
    if (_current_op != nfc_eeprom_idle) {
        if (_delegate != NULL) {
            _delegate->on_ndef_message_erased(NFC_ERR_BUSY);
        }
        return;
    }
    _current_op = nfc_eeprom_erase_start_session;

    // Reset EEPROM address
    _eeprom_address = 0;

    // Go through the steps!
    _driver->start_session();

    // 1 - Start session
    // 2 - Set addressable size to the max
    // 3 - Erase bytes (can be repeated)
    // 4 - Set addressable size to 0
    // 5 - End session
}

void NFCEEPROM::on_session_started(bool success)
{
    switch (_current_op) {
        case nfc_eeprom_write_start_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER); // An EEPROM is not really a controller but close enough
                return;
            }
            _current_op = nfc_eeprom_write_write_size;
            _driver->write_size(ac_buffer_reader_readable(&_ndef_buffer_reader));
            break;

        case nfc_eeprom_read_start_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }
            _current_op = nfc_eeprom_read_read_size;
            _driver->read_size();
            break;

        case nfc_eeprom_erase_start_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            _current_op = nfc_eeprom_erase_write_max_size;
            _driver->write_size(_driver->read_max_size());
            break;

        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_session_ended(bool success)
{
    switch (_current_op) {
        case nfc_eeprom_write_end_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }
            _current_op = nfc_eeprom_idle;
            if (_delegate != NULL) {
                _delegate->on_ndef_message_written(_operation_result);
            }
            break;

        case nfc_eeprom_read_end_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }
            _current_op = nfc_eeprom_idle;

            // Try to parse the NDEF message
            ndef_msg_decode(ndef_message());

            if (_delegate != NULL) {
                _delegate->on_ndef_message_read(_operation_result);
            }
            break;

        case nfc_eeprom_erase_end_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }
            _current_op = nfc_eeprom_idle;
            if (_delegate != NULL) {
                _delegate->on_ndef_message_erased(_operation_result);
            }
            break;

        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_bytes_read(size_t count)
{
    switch (_current_op) {
        case nfc_eeprom_read_read_bytes: {
            if (count == 0) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Discard bytes that were actually read and update address
            _eeprom_address += count;
            ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
            ac_buffer_builder_write_n_skip(buffer_builder, count);

            // Continue reading
            _event_queue->call(this, &NFCEEPROM::continue_read);
            break;
        }
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_bytes_written(size_t count)
{
    switch (_current_op) {
        case nfc_eeprom_write_write_bytes:
            if (count == 0) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Skip bytes that were actually written and update address
            _eeprom_address += count;
            ac_buffer_read_n_skip(&_ndef_buffer_reader, count);

            // Continue writing
            _event_queue->call(this, &NFCEEPROM::continue_write);
            break;
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_size_written(bool success)
{
    switch (_current_op) {
        case nfc_eeprom_write_write_size:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            _current_op = nfc_eeprom_write_write_bytes;
            continue_write();
            break;
        case nfc_eeprom_erase_write_max_size:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Start erasing bytes
            _current_op = nfc_eeprom_erase_erase_bytes;
            continue_erase();
            break;
        case nfc_eeprom_erase_write_0_size:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // End session
            _current_op = nfc_eeprom_erase_end_session;
            _operation_result = NFC_OK;
            _driver->end_session();
            break;
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_size_read(bool success, size_t size)
{
    switch (_current_op) {
        case nfc_eeprom_read_read_size: {
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Reset NDEF message buffer builder
            ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
            ac_buffer_builder_reset(buffer_builder);

            // Check that we have a big enough buffer to read the message
            if (size > ac_buffer_builder_writable(buffer_builder)) {
                // Not enough space, close session
                _current_op = nfc_eeprom_read_end_session;
                _operation_result = NFC_ERR_BUFFER_TOO_SMALL;
                _driver->end_session();
                return;
            }

            // Save size and reset address
            _eeprom_address = 0;
            _ndef_buffer_read_sz = size;

            // Start reading bytes
            _current_op = nfc_eeprom_read_read_bytes;
            _event_queue->call(this, &NFCEEPROM::continue_read);
            break;
        }
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_bytes_erased(size_t count)
{

    switch (_current_op) {
        case nfc_eeprom_erase_erase_bytes:
            if (count == 0) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Update address
            _eeprom_address += count;

            // Continue erasing
            _event_queue->call(this, &NFCEEPROM::continue_erase);
            break;
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::continue_write()
{
    if (ac_buffer_reader_readable(&_ndef_buffer_reader) > 0) {
        // Continue writing
        _driver->write_bytes(_eeprom_address, ac_buffer_reader_current_buffer_pointer(&_ndef_buffer_reader), ac_buffer_reader_current_buffer_length(&_ndef_buffer_reader));
    } else {
        // we are done
        _current_op = nfc_eeprom_write_end_session;
        _operation_result = NFC_OK;
        _driver->end_session();
    }
}

void NFCEEPROM::continue_erase()
{
    if (_eeprom_address < _driver->read_max_size()) {
        // Continue erasing
        _driver->erase_bytes(_eeprom_address, _driver->read_max_size() - _eeprom_address);
    } else {
        // Now update size
        _current_op = nfc_eeprom_erase_write_0_size;
        _driver->write_size(0);
    }
}

void NFCEEPROM::continue_read()
{
    if (_eeprom_address < _ndef_buffer_read_sz) {
        // Continue reading
        ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
        _driver->read_bytes(_eeprom_address, ac_buffer_builder_write_position(buffer_builder), _ndef_buffer_read_sz - _eeprom_address);
    } else {
        // Done, close session
        _current_op = nfc_eeprom_read_end_session;
        _operation_result = NFC_OK;
        _driver->end_session();
    }
}

void NFCEEPROM::handle_error(nfc_err_t ret)
{
    // Save & reset current op
    nfc_eeprom_operation_t last_op = _current_op;
    _current_op = nfc_eeprom_idle;

    if (_delegate != NULL) {
        if (last_op <= nfc_eeprom_write_end_session) {
            _delegate->on_ndef_message_written(ret);
        } else if (last_op <= nfc_eeprom_read_end_session) {
            _delegate->on_ndef_message_read(ret);
        } else if (last_op <= nfc_eeprom_erase_end_session) {
            _delegate->on_ndef_message_erased(ret);
        }
    }
}

NFCNDEFCapable::Delegate *NFCEEPROM::ndef_capable_delegate()
{
    return _delegate;
}
<commit_msg>NFCEEPROM: fixes a compiler warning<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "NFCEEPROM.h"
#include "ndef/ndef.h"

using namespace mbed;
using namespace mbed::nfc;

NFCEEPROM::NFCEEPROM(NFCEEPROMDriver *driver, events::EventQueue *queue, const Span<uint8_t> &ndef_buffer)
    :
    NFCTarget(ndef_buffer), _delegate(NULL), _driver(driver), _event_queue(queue), _initialized(false),
    _current_op(nfc_eeprom_idle), _ndef_buffer_reader { nullptr, 0, nullptr }, _ndef_buffer_read_sz(0),
    _eeprom_address(0), _operation_result(NFC_ERR_UNKNOWN)
{
    _driver->set_delegate(this);
    _driver->set_event_queue(queue);
}

nfc_err_t NFCEEPROM::initialize()
{
    MBED_ASSERT(_initialized == false); // Initialize should only be called once

    // Initialize driver
    _driver->reset();
    _initialized = true;
    return NFC_OK;
}

void NFCEEPROM::set_delegate(NFCEEPROM::Delegate *delegate)
{
    _delegate = delegate;
}

void NFCEEPROM::write_ndef_message()
{
    MBED_ASSERT(_initialized == true);
    if (_current_op != nfc_eeprom_idle) {
        if (_delegate != NULL) {
            _delegate->on_ndef_message_written(NFC_ERR_BUSY);
        }
        return;
    }

    // First update NDEF message if required
    ndef_msg_encode(ndef_message());

    _current_op = nfc_eeprom_write_start_session;

    // Retrieve reader
    ac_buffer_dup(&_ndef_buffer_reader, ac_buffer_builder_buffer(ndef_msg_buffer_builder(ndef_message())));

    // Check that NDEF message is not too big
    if (ac_buffer_reader_readable(&_ndef_buffer_reader) > _driver->read_max_size()) {
        handle_error(NFC_ERR_BUFFER_TOO_SMALL);
        return;
    }

    // Reset EEPROM address
    _eeprom_address = 0;
    // Go through the steps!
    _driver->start_session();

    // 1 - Start session
    // 2 - Write bytes (can be repeated)
    // 3 - Set NDEF message size
    // 4 - End session
}

void NFCEEPROM::read_ndef_message()
{
    MBED_ASSERT(_initialized == true);
    if (_current_op != nfc_eeprom_idle) {
        if (_delegate != NULL) {
            _delegate->on_ndef_message_written(NFC_ERR_BUSY);
        }
        return;
    }
    _current_op = nfc_eeprom_read_start_session;

    // Reset EEPROM address
    _eeprom_address = 0;

    // Go through the steps!
    _driver->start_session();

    // 1 - Start session
    // 2 - Get NDEF message size
    // 3 - Read bytes (can be repeated)
    // 4 - End session
}

void NFCEEPROM::erase_ndef_message()
{
    // We don't want to take any risks, so erase the whole address space
    // And set the message size to 0

    MBED_ASSERT(_initialized == true);
    if (_current_op != nfc_eeprom_idle) {
        if (_delegate != NULL) {
            _delegate->on_ndef_message_erased(NFC_ERR_BUSY);
        }
        return;
    }
    _current_op = nfc_eeprom_erase_start_session;

    // Reset EEPROM address
    _eeprom_address = 0;

    // Go through the steps!
    _driver->start_session();

    // 1 - Start session
    // 2 - Set addressable size to the max
    // 3 - Erase bytes (can be repeated)
    // 4 - Set addressable size to 0
    // 5 - End session
}

void NFCEEPROM::on_session_started(bool success)
{
    switch (_current_op) {
        case nfc_eeprom_write_start_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER); // An EEPROM is not really a controller but close enough
                return;
            }
            _current_op = nfc_eeprom_write_write_size;
            _driver->write_size(ac_buffer_reader_readable(&_ndef_buffer_reader));
            break;

        case nfc_eeprom_read_start_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }
            _current_op = nfc_eeprom_read_read_size;
            _driver->read_size();
            break;

        case nfc_eeprom_erase_start_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            _current_op = nfc_eeprom_erase_write_max_size;
            _driver->write_size(_driver->read_max_size());
            break;

        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_session_ended(bool success)
{
    switch (_current_op) {
        case nfc_eeprom_write_end_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }
            _current_op = nfc_eeprom_idle;
            if (_delegate != NULL) {
                _delegate->on_ndef_message_written(_operation_result);
            }
            break;

        case nfc_eeprom_read_end_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }
            _current_op = nfc_eeprom_idle;

            // Try to parse the NDEF message
            ndef_msg_decode(ndef_message());

            if (_delegate != NULL) {
                _delegate->on_ndef_message_read(_operation_result);
            }
            break;

        case nfc_eeprom_erase_end_session:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }
            _current_op = nfc_eeprom_idle;
            if (_delegate != NULL) {
                _delegate->on_ndef_message_erased(_operation_result);
            }
            break;

        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_bytes_read(size_t count)
{
    switch (_current_op) {
        case nfc_eeprom_read_read_bytes: {
            if (count == 0) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Discard bytes that were actually read and update address
            _eeprom_address += count;
            ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
            ac_buffer_builder_write_n_skip(buffer_builder, count);

            // Continue reading
            _event_queue->call(this, &NFCEEPROM::continue_read);
            break;
        }
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_bytes_written(size_t count)
{
    switch (_current_op) {
        case nfc_eeprom_write_write_bytes:
            if (count == 0) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Skip bytes that were actually written and update address
            _eeprom_address += count;
            ac_buffer_read_n_skip(&_ndef_buffer_reader, count);

            // Continue writing
            _event_queue->call(this, &NFCEEPROM::continue_write);
            break;
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_size_written(bool success)
{
    switch (_current_op) {
        case nfc_eeprom_write_write_size:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            _current_op = nfc_eeprom_write_write_bytes;
            continue_write();
            break;
        case nfc_eeprom_erase_write_max_size:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Start erasing bytes
            _current_op = nfc_eeprom_erase_erase_bytes;
            continue_erase();
            break;
        case nfc_eeprom_erase_write_0_size:
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // End session
            _current_op = nfc_eeprom_erase_end_session;
            _operation_result = NFC_OK;
            _driver->end_session();
            break;
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_size_read(bool success, size_t size)
{
    switch (_current_op) {
        case nfc_eeprom_read_read_size: {
            if (!success) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Reset NDEF message buffer builder
            ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
            ac_buffer_builder_reset(buffer_builder);

            // Check that we have a big enough buffer to read the message
            if (size > ac_buffer_builder_writable(buffer_builder)) {
                // Not enough space, close session
                _current_op = nfc_eeprom_read_end_session;
                _operation_result = NFC_ERR_BUFFER_TOO_SMALL;
                _driver->end_session();
                return;
            }

            // Save size and reset address
            _eeprom_address = 0;
            _ndef_buffer_read_sz = size;

            // Start reading bytes
            _current_op = nfc_eeprom_read_read_bytes;
            _event_queue->call(this, &NFCEEPROM::continue_read);
            break;
        }
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::on_bytes_erased(size_t count)
{

    switch (_current_op) {
        case nfc_eeprom_erase_erase_bytes:
            if (count == 0) {
                handle_error(NFC_ERR_CONTROLLER);
                return;
            }

            // Update address
            _eeprom_address += count;

            // Continue erasing
            _event_queue->call(this, &NFCEEPROM::continue_erase);
            break;
        default:
            // Should not happen, state machine is broken or driver is doing something wrong
            handle_error(NFC_ERR_UNKNOWN);
            return;
    }
}

void NFCEEPROM::continue_write()
{
    if (ac_buffer_reader_readable(&_ndef_buffer_reader) > 0) {
        // Continue writing
        _driver->write_bytes(_eeprom_address, ac_buffer_reader_current_buffer_pointer(&_ndef_buffer_reader), ac_buffer_reader_current_buffer_length(&_ndef_buffer_reader));
    } else {
        // we are done
        _current_op = nfc_eeprom_write_end_session;
        _operation_result = NFC_OK;
        _driver->end_session();
    }
}

void NFCEEPROM::continue_erase()
{
    if (_eeprom_address < _driver->read_max_size()) {
        // Continue erasing
        _driver->erase_bytes(_eeprom_address, _driver->read_max_size() - _eeprom_address);
    } else {
        // Now update size
        _current_op = nfc_eeprom_erase_write_0_size;
        _driver->write_size(0);
    }
}

void NFCEEPROM::continue_read()
{
    if (_eeprom_address < _ndef_buffer_read_sz) {
        // Continue reading
        ac_buffer_builder_t *buffer_builder = ndef_msg_buffer_builder(ndef_message());
        _driver->read_bytes(_eeprom_address, ac_buffer_builder_write_position(buffer_builder), _ndef_buffer_read_sz - _eeprom_address);
    } else {
        // Done, close session
        _current_op = nfc_eeprom_read_end_session;
        _operation_result = NFC_OK;
        _driver->end_session();
    }
}

void NFCEEPROM::handle_error(nfc_err_t ret)
{
    // Save & reset current op
    nfc_eeprom_operation_t last_op = _current_op;
    _current_op = nfc_eeprom_idle;

    if (_delegate != NULL) {
        if (last_op <= nfc_eeprom_write_end_session) {
            _delegate->on_ndef_message_written(ret);
        } else if (last_op <= nfc_eeprom_read_end_session) {
            _delegate->on_ndef_message_read(ret);
        } else if (last_op <= nfc_eeprom_erase_end_session) {
            _delegate->on_ndef_message_erased(ret);
        }
    }
}

NFCNDEFCapable::Delegate *NFCEEPROM::ndef_capable_delegate()
{
    return _delegate;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////
// This file is part of Grappa, a system for scaling irregular
// applications on commodity clusters.

// Copyright (C) 2010-2014 University of Washington and Battelle
// Memorial Institute. University of Washington authorizes use of this
// Grappa software.

// Grappa is free software: you can redistribute it and/or modify it
// under the terms of the Affero General Public License as published
// by Affero, Inc., either version 1 of the License, or (at your
// option) any later version.

// Grappa 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
// Affero General Public License for more details.

// You should have received a copy of the Affero General Public
// License along with this program. If not, you may obtain one from
// http://www.affero.org/oagpl.html.
////////////////////////////////////////////////////////////////////////

#pragma once

#include "MetricBase.hpp"
#include <glog/logging.h>

#ifdef VTRACE
#include <vt_user.h>
#endif

#ifdef GOOGLE_PROFILER
#include <gperftools/profiler.h>
#endif

#include <functional>
#include <string>
#include <cstdio>

namespace Grappa {
  /// @addtogroup Utility
  /// @{

  /// Metric that simply keeps track of a single string value over time.
  /// Typically used as a counter, but can also be used for sampling an instantaneous value.

  // Design note: We chose not to use template specialization
  // on SimpleMetric because enough methods would have to be specialized that it isn't worth it
  class StringMetric : public impl::MetricBase {
  public:
    enum { max_string_size = 2048 };

    // utility for safe writing using max_string_size
    static void write_chars(char * dst, std::string newstr, std::string name="(anonymous)") {
      auto written = snprintf(dst, max_string_size, "%s", newstr.c_str());
      CHECK( written < max_string_size ) << "StringMetric " << name << " got assigned longer than max " << max_string_size;
      CHECK( written >= 0 ) << "StringMetric " << name << " assignment failure (code=" << written << ")";
    }

  private:
    void write_value(std::string newstr) {
      write_chars(this->value_, newstr, this->name);
    }

  protected:
    typedef std::function<std::string(void)> InitFn;
    std::string initial_value;
    char value_[max_string_size]; // store as a fixed size cstr so we can move it around
    InitFn initf_;

#ifdef VTRACE_SAMPLED
    unsigned vt_counter;
    static const int vt_type;

    void vt_sample() const;
#endif

  public:
    StringMetric(const char * name, std::string initial_value, bool reg_new = true):
        initial_value(initial_value), initf_(NULL), impl::MetricBase(name, reg_new) {
          write_value(initial_value);
#ifdef VTRACE_SAMPLED
        if (StringMetric::vt_type == -1) {
          LOG(ERROR) << "warning: VTrace sampling unsupported for this type of StringMetric.";
        } else {
          vt_counter = VT_COUNT_DEF(name, name, StringMetric::vt_type, VT_COUNT_DEFGROUP);
        }
#endif
    }

    virtual std::ostream& json(std::ostream& o) const {
      o << '"' << name << "\": " << value_;
      return o;
    }

    virtual void reset() {
      if (initf_ != NULL) {
        write_value(initf_());
      } else {
        write_value(initial_value);
      }
    }

    virtual void sample() {
#ifdef VTRACE_SAMPLED
      // vt_sample() specialized for supported tracing types in Metrics.cpp
      vt_sample();
#endif
    }

    virtual StringMetric* clone() const {
      // (note: must do `reg_new`=false so we don't re-register this stat)
      StringMetric x(name, std::string(value_), false);
#if DEBUG
      this->json(VLOG(4) << "cloned is ");
      x.json(VLOG(4) << "clone is ");
#endif
      return new StringMetric(name, std::string(value_), false);
    }

    virtual void merge_all(impl::MetricBase* static_stat_ptr);

    /// Get the current value
    inline std::string value() const { return std::string(value_); }

    // <sugar>
    inline const StringMetric& operator+=(std::string appended) {
      auto newstr = std::string(value_) + appended;
      write_value(newstr);
      return *this;
    }

    // allow casting as just the value
    inline operator std::string() const { return std::string(value_); }

    inline StringMetric& operator=(std::string value) {
      write_value(value);
      return *this;
    }
    // </sugar>
  };

  /// @}
} // namespace Grappa
<commit_msg>fixes 177<commit_after>////////////////////////////////////////////////////////////////////////
// This file is part of Grappa, a system for scaling irregular
// applications on commodity clusters.

// Copyright (C) 2010-2014 University of Washington and Battelle
// Memorial Institute. University of Washington authorizes use of this
// Grappa software.

// Grappa is free software: you can redistribute it and/or modify it
// under the terms of the Affero General Public License as published
// by Affero, Inc., either version 1 of the License, or (at your
// option) any later version.

// Grappa 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
// Affero General Public License for more details.

// You should have received a copy of the Affero General Public
// License along with this program. If not, you may obtain one from
// http://www.affero.org/oagpl.html.
////////////////////////////////////////////////////////////////////////

#pragma once

#include "MetricBase.hpp"
#include <glog/logging.h>

#ifdef VTRACE
#include <vt_user.h>
#endif

#ifdef GOOGLE_PROFILER
#include <gperftools/profiler.h>
#endif

#include <functional>
#include <string>
#include <cstdio>
#include <sstream>

namespace Grappa {
  /// @addtogroup Utility
  /// @{

  /// Metric that simply keeps track of a single string value over time.
  /// Typically used as a counter, but can also be used for sampling an instantaneous value.

  // Design note: We chose not to use template specialization
  // on SimpleMetric because enough methods would have to be specialized that it isn't worth it
  class StringMetric : public impl::MetricBase {
  public:
    enum { max_string_size = 2048 };

    // utility for safe writing using max_string_size
    static void write_chars(char * dst, std::string newstr, std::string name="(anonymous)") {
      auto written = snprintf(dst, max_string_size, "%s", newstr.c_str());
      CHECK( written < max_string_size ) << "StringMetric " << name << " got assigned longer than max " << max_string_size;
      CHECK( written >= 0 ) << "StringMetric " << name << " assignment failure (code=" << written << ")";
    }

  private:
    void write_value(std::string newstr) {
      write_chars(this->value_, newstr, this->name);
    }

  protected:
    typedef std::function<std::string(void)> InitFn;
    std::string initial_value;
    char value_[max_string_size]; // store as a fixed size cstr so we can move it around
    InitFn initf_;

#ifdef VTRACE_SAMPLED
    unsigned vt_counter;
    static const int vt_type;

    void vt_sample() const;
#endif

  public:
    StringMetric(const char * name, std::string initial_value, bool reg_new = true):
        initial_value(initial_value), initf_(NULL), impl::MetricBase(name, reg_new) {
          write_value(initial_value);
#ifdef VTRACE_SAMPLED
        if (StringMetric::vt_type == -1) {
          LOG(ERROR) << "warning: VTrace sampling unsupported for this type of StringMetric.";
        } else {
          vt_counter = VT_COUNT_DEF(name, name, StringMetric::vt_type, VT_COUNT_DEFGROUP);
        }
#endif
    }

    virtual std::ostream& json(std::ostream& o) const {
      o << '"' << name << "\": " << value_;
      return o;
    }

    virtual void reset() {
      if (initf_ != NULL) {
        write_value(initf_());
      } else {
        write_value(initial_value);
      }
    }

    virtual void sample() {
#ifdef VTRACE_SAMPLED
      // vt_sample() specialized for supported tracing types in Metrics.cpp
      vt_sample();
#endif
    }

    virtual StringMetric* clone() const {
      // (note: must do `reg_new`=false so we don't re-register this stat)
      StringMetric x(name, std::string(value_), false);
#if DEBUG
      std::ostringstream o;
      this->json(o << "cloned is ");
      x.json(o << "clone is ");
      VLOG(4) << o.str();
#endif
      return new StringMetric(name, std::string(value_), false);
    }

    virtual void merge_all(impl::MetricBase* static_stat_ptr);

    /// Get the current value
    inline std::string value() const { return std::string(value_); }

    // <sugar>
    inline const StringMetric& operator+=(std::string appended) {
      auto newstr = std::string(value_) + appended;
      write_value(newstr);
      return *this;
    }

    // allow casting as just the value
    inline operator std::string() const { return std::string(value_); }

    inline StringMetric& operator=(std::string value) {
      write_value(value);
      return *this;
    }
    // </sugar>
  };

  /// @}
} // namespace Grappa
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

template <class T> class malloc_allocator
{
	public:
		typedef T                 value_type;
		typedef value_type*       pointer;
		typedef const value_type* const_pointer;
		typedef value_type&       reference;
		typedef const value_type& const_reference;
		typedef std::size_t       size_type;
		typedef std::ptrdiff_t    difference_type;

		template <class U>
		struct rebind { typedef malloc_allocator<U> other; };

		malloc_allocator()
		{
			std::cout << "Created a malloc_allocator" << std::endl;
		}

		malloc_allocator(const malloc_allocator&)
		{
			std::cout << "Copied a malloc_allocator" << std::endl;
		}

		template <class U>
		malloc_allocator(const malloc_allocator<U>&) {}

		~malloc_allocator()
		{
			std::cout << "Deleted a malloc_allocator" << std::endl;
		}

		pointer address(reference x) const { return &x; }

		const_pointer address(const_reference x) const
		{
			return x;
		}

		pointer allocate(size_type n, const_pointer = 0)
		{
			void* p = std::malloc(n * sizeof(T));
			if (!p)
				throw std::bad_alloc();

			std::cout << "Allocated a block of memory of size "
				<< n*sizeof(T) << std::endl;

			return static_cast<pointer>(p);
		}

		void deallocate(pointer p, size_type)
		{
			std::free(p);
		}

		size_type max_size() const
		{
			return static_cast<size_type>(-1) / sizeof(T);
		}

		void construct(pointer p, const value_type&& x)
		{
			std::cout << "Move constructed an object" << std::endl;
			new(p) value_type(x);
		}

		void construct(pointer p, const value_type& x)
		{
			std::cout << "Copy constructed an object" << std::endl;
			new(p) value_type(x);
		}

		void destroy(pointer p)
		{
		  std::cout << "Destroyed an object" << std::endl;
			p->~value_type();
		}

	private:
		void operator=(const malloc_allocator&);
};

template<> class malloc_allocator<void>
{
	typedef void        value_type;
	typedef void*       pointer;
	typedef const void* const_pointer;

	template <class U>
		struct rebind { typedef malloc_allocator<U> other; };
};

template <class T>
inline bool operator==(const malloc_allocator<T>&,
		const malloc_allocator<T>&)
{
	return true;
}

template <class T>
inline bool operator!=(const malloc_allocator<T>&,
		const malloc_allocator<T>&)
{
	return false;
}

class NonCopyable
{
	public:
		NonCopyable() { }

		NonCopyable(const NonCopyable&& ) { }

	private:
		NonCopyable(const NonCopyable&) = delete;
};

int main(int argc, char* argv[])
{
	std::vector<NonCopyable,malloc_allocator<NonCopyable>> myVector;
	//myVector.reserve(32);
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
	myVector.push_back(NonCopyable());
}

<commit_msg>Corrections<commit_after>#include <iostream>
#include <vector>

template <class T> class malloc_allocator
{
	public:
		typedef T                 value_type;
		typedef value_type*       pointer;
		typedef const value_type* const_pointer;
		typedef value_type&       reference;
		typedef const value_type& const_reference;
		typedef std::size_t       size_type;
		typedef std::ptrdiff_t    difference_type;

		template <class U>
		struct rebind { typedef malloc_allocator<U> other; };

		malloc_allocator()
		{
			std::cout << "Created a malloc_allocator" << std::endl;
		}

		malloc_allocator(const malloc_allocator&)
		{
			std::cout << "Copied a malloc_allocator" << std::endl;
		}

		template <class U>
		malloc_allocator(const malloc_allocator<U>&) {}

		~malloc_allocator()
		{
			std::cout << "Deleted a malloc_allocator" << std::endl;
		}

		pointer address(reference x) const { return &x; }

		const_pointer address(const_reference x) const
		{
			return x;
		}

		pointer allocate(size_type n, const_pointer = 0)
		{
			void* p = std::malloc(n * sizeof(T));
			if (!p)
				throw std::bad_alloc();

			std::cout << "Allocated a block of memory of size "
				<< n*sizeof(T) << std::endl;

			return static_cast<pointer>(p);
		}

		void deallocate(pointer p, size_type)
		{
			std::free(p);
		}

		size_type max_size() const
		{
			return static_cast<size_type>(-1) / sizeof(T);
		}

		/*void construct(pointer p, const value_type&& x)
		{
			std::cout << "Move constructed an object" << std::endl;
			new(p) value_type(x);
		}*/

		void construct(pointer p, const value_type& x)
		{
			std::cout << "Copy constructed an object" << std::endl;
			new(p) value_type(x);
		}

		void destroy(pointer p)
		{
		  std::cout << "Destroyed an object" << std::endl;
			p->~value_type();
		}

	private:
		void operator=(const malloc_allocator&);
};

template<> class malloc_allocator<void>
{
	typedef void        value_type;
	typedef void*       pointer;
	typedef const void* const_pointer;

	template <class U>
		struct rebind { typedef malloc_allocator<U> other; };
};

template <class T>
inline bool operator==(const malloc_allocator<T>&,
		const malloc_allocator<T>&)
{
	return true;
}

template <class T>
inline bool operator!=(const malloc_allocator<T>&,
		const malloc_allocator<T>&)
{
	return false;
}

class NonCopyable
{
	public:
		NonCopyable() { }

		NonCopyable(NonCopyable&& ) { }

	private:
		NonCopyable(const NonCopyable&) = delete;
};

int main(int argc, char* argv[])
{
	std::vector<NonCopyable,malloc_allocator<NonCopyable>> myVector;
	myVector.reserve(32);
	myVector.push_back(NonCopyable());
}

<|endoftext|>


<commit_before>#include "../header/vns-priv.hpp"

using namespace pcp;
using namespace std;
using namespace boost;

const string changeColor::getName() {
	return "changeColor";
}

const char changeColor::getAbbreviation() {
	return getStaticAbbreviation();
}

const char changeColor::getStaticAbbreviation() {
	return 'c' ;
}

Solution *changeColor::findLocalMin(Solution& curBest, Solution& full) {
	Solution *s = &curBest;
	int maxColor = curBest.colorsUsed - 1;
	const int ITER_MAX = s->numParts * 20;
	pair<VertexIter, VertexIter> vIter;
	VertexPart_Map vParts = get(vertex_index1_t(), *s->g);

	if (DEBUG_LEVEL > 2) {
		cout<<"Starting changeColor"<<endl;
	}

	/// Change the color of all nodes with maxColor to a random color
	for (vIter = vertices(*s->g); vIter.first != vIter.second; vIter.first++) {
		if (s->getPartitionColor(*vIter.first) == maxColor) {
			int col = rand() % maxColor;
			s->setPartitionColor(*vIter.first, col);
			if (DEBUG_LEVEL > 3) {
				cout<<"Recoloring "<<*vIter.first<<" with color ";
				cout<<col<<endl;
			}
		}
	}

	pair<AdjIter, AdjIter> ai;
	int colors[s->numParts];
	int i = 0;
	int iter = 0;
	std::vector<Vertex> conflicts;

	/// Add all conflicting nodes to vector "conflicts"
	for (vIter = vertices(*s->g); vIter.first != vIter.second;
			  vIter.first++) {

		for (ai = adjacent_vertices(*vIter.first, *s->g);
			  ai.first != ai.second; ai.first++) {

			if (s->getPartitionColor(*ai.first) ==
				 s->getPartitionColor(*vIter.first)) {

				if (DEBUG_LEVEL > 3) {
					cout<<"Conflicting node "<<*vIter.first<< " with color ";
					cout<<s->partition[vParts[*vIter.first]]<<" added to conflicts";
					cout<<endl;
				}
				conflicts.push_back(*vIter.first);
				break;
			}
		}
	}

	/// Run until there are no more conflicts, or the iteration limit has been
	/// reached
	while (conflicts.size() != 0 && iter < ITER_MAX) {
		iter++;

		/// Choose random conflicting node for recoloring
		int random = rand() % conflicts.size();

		if (DEBUG_LEVEL > 3) {
			cout<<"Chose conflicting node "<<conflicts[random]<<endl;
		}

		for (i = 0; i < s->numParts; i++) {
			colors[i] = 0;
		}

		for (ai = adjacent_vertices(conflicts[random], *s->g);
			  ai.first != ai.second; ai.first++) {

			colors[s->getPartitionColor(*ai.first)] = 1;
		}

		/// Search for new suitable color for Node
		bool found = false;
		for (i = 0; i < maxColor && !found; i++) {
			if (colors[i] == 0) {
				if (DEBUG_LEVEL > 3) {
					cout<<"Found new suitable color "<<i<<" for Node ";
					cout<<conflicts[random]<<endl;
				}

				found = true;
				s->setPartitionColor(conflicts[random], i);
				break;
			}
		}
		/// No suitable color found, try random recoloring of node
		if (!found) {
			int col = rand() % maxColor;
			s->setPartitionColor(conflicts[random], col);
			if (DEBUG_LEVEL > 3) {
				cout<<"Recolor node "<<conflicts[random]<<" with color ";
				cout<<col<<endl;
			}

			/// Search for conflicts with the randomly recolored node
			pair<AdjIter, AdjIter> aIter;
			for (aIter = adjacent_vertices(conflicts[random], *s->g);
				  aIter.first != aIter.second; aIter.first++) {

				for (i = 0; i < s->numParts; i++) {
					colors[i] = 0;
				}

				for (ai = adjacent_vertices(*aIter.first, *s->g);
					  ai.first != ai.second; ai.first++) {

					colors[s->getPartitionColor(*ai.first)] = 1;
				}

				/// Try recoloring conflicting nodes
				bool found = false;
				for (i = 0; i < maxColor && !found; i++) {
					if (colors[i] == 0) {
						if (DEBUG_LEVEL > 3) {
							cout<<"Found new suitable color "<<i<<" for Node ";
							cout<<*aIter.first<<endl;
						}
						found = true;
						s->setPartitionColor(*aIter.first, i);
						break;
					}
				}
				/// Conflict could not be resolved
				if (!found) {
					if (DEBUG_LEVEL > 2) {
						cout<<"Conflict could not be resolved for Node ";
						cout<<*aIter.first<<endl;
					}
				}
			}
		}

		/// Rebuild conflicting nodes
		conflicts.clear();
		for (vIter = vertices(*s->g); vIter.first != vIter.second;
			  vIter.first++) {

			for (ai = adjacent_vertices(*vIter.first, *s->g);
				  ai.first != ai.second; ai.first++) {

				if (s->getPartitionColor(*ai.first) ==
					 s->getPartitionColor(*vIter.first)) {

					if (DEBUG_LEVEL > 3) {
						cout<<"Conflicting node "<<*vIter.first<< " with color ";
						cout<<s->partition[vParts[*vIter.first]]<<" added to conflicts";
						cout<<endl;
					}
					conflicts.push_back(*vIter.first);
					break;
				}
			}
		}
	}

	/// New solution is not conflict free, return curBest
	if (conflicts.size() != 0) {
		if (DEBUG_LEVEL > 1) {
			cout<<"Conflict found"<<endl;
		}
		s->colorsUsed = s->numParts;
		return s;
	}

	/// New solution is conflict free, count colorsUsed and return
	else {
		maxColor = 0;
		for (int i = 0; i < s->numParts; i++) {

			if (s->partition[i] > maxColor) {
				maxColor = s->partition[i];
			}
		}
		s->colorsUsed = maxColor + 1;

		if (DEBUG_LEVEL > 1) {
			cout<<"Change Color uses "<<s->colorsUsed<<" colors"<<endl;
		}

		Solution *temp = new Solution(s);
		temp = this->findLocalMin(*temp, full);
		if (temp->colorsUsed < s->colorsUsed) {
			delete s;
			s = temp;
		}
		else
			delete temp;
	}
	return s;
}

/// Reset all colors to unset, then proceed by selecting a node randomly,
/// recolor it with the least possible color. Proceed until all nodes are
/// colored
Solution *changeColor::shuffleSolution(Solution& cur, Solution& full,
				 							  int numSteps) {
	if (DEBUG_LEVEL > 3) {
		cout<<"Shaking with changeColor with"<<endl;
	}

	Solution *ret = &cur;
	vector<Vertex> uncolored;

	/// Reset all colors
	for (int i = 0; i < numSteps; i++) {
		uncolored.push_back(i % ret->numParts);
	}

	random_shuffle(uncolored.begin(), uncolored.end());
	/// Proceed until all nodes are colored
	Vertex node = 0;
	int color;
	int maxColor = ret->colorsUsed - 1;
	while (uncolored.size() != 0) {
		node = uncolored.back();
		uncolored.pop_back();
		color = ret->minPossibleColor(node);
		ret->setPartitionColor(node, color);
		if (color > maxColor)
			maxColor = color;
	}
	ret->colorsUsed = maxColor + 1;

	return ret;
}
<commit_msg>Rewrote shaking in changeColor<commit_after>#include "../header/vns-priv.hpp"

using namespace pcp;
using namespace std;
using namespace boost;

const string changeColor::getName() {
	return "changeColor";
}

const char changeColor::getAbbreviation() {
	return getStaticAbbreviation();
}

const char changeColor::getStaticAbbreviation() {
	return 'c' ;
}

Solution *changeColor::findLocalMin(Solution& curBest, Solution& full) {
	Solution *s = &curBest;
	int maxColor = curBest.colorsUsed - 1;
	const int ITER_MAX = s->numParts * 20;
	pair<VertexIter, VertexIter> vIter;
	VertexPart_Map vParts = get(vertex_index1_t(), *s->g);

	if (DEBUG_LEVEL > 2) {
		cout<<"Starting changeColor"<<endl;
	}

	/// Change the color of all nodes with maxColor to a random color
	for (vIter = vertices(*s->g); vIter.first != vIter.second; vIter.first++) {
		if (s->getPartitionColor(*vIter.first) == maxColor) {
			int col = rand() % maxColor;
			s->setPartitionColor(*vIter.first, col);
			if (DEBUG_LEVEL > 3) {
				cout<<"Recoloring "<<*vIter.first<<" with color ";
				cout<<col<<endl;
			}
		}
	}

	pair<AdjIter, AdjIter> ai;
	int colors[s->numParts];
	int i = 0;
	int iter = 0;
	std::vector<Vertex> conflicts;

	/// Add all conflicting nodes to vector "conflicts"
	for (vIter = vertices(*s->g); vIter.first != vIter.second;
			  vIter.first++) {

		for (ai = adjacent_vertices(*vIter.first, *s->g);
			  ai.first != ai.second; ai.first++) {

			if (s->getPartitionColor(*ai.first) ==
				 s->getPartitionColor(*vIter.first)) {

				if (DEBUG_LEVEL > 3) {
					cout<<"Conflicting node "<<*vIter.first<< " with color ";
					cout<<s->partition[vParts[*vIter.first]]<<" added to conflicts";
					cout<<endl;
				}
				conflicts.push_back(*vIter.first);
				break;
			}
		}
	}

	/// Run until there are no more conflicts, or the iteration limit has been
	/// reached
	while (conflicts.size() != 0 && iter < ITER_MAX) {
		iter++;

		/// Choose random conflicting node for recoloring
		int random = rand() % conflicts.size();

		if (DEBUG_LEVEL > 3) {
			cout<<"Chose conflicting node "<<conflicts[random]<<endl;
		}

		for (i = 0; i < s->numParts; i++) {
			colors[i] = 0;
		}

		for (ai = adjacent_vertices(conflicts[random], *s->g);
			  ai.first != ai.second; ai.first++) {

			colors[s->getPartitionColor(*ai.first)] = 1;
		}

		/// Search for new suitable color for Node
		bool found = false;
		for (i = 0; i < maxColor && !found; i++) {
			if (colors[i] == 0) {
				if (DEBUG_LEVEL > 3) {
					cout<<"Found new suitable color "<<i<<" for Node ";
					cout<<conflicts[random]<<endl;
				}

				found = true;
				s->setPartitionColor(conflicts[random], i);
				break;
			}
		}
		/// No suitable color found, try random recoloring of node
		if (!found) {
			int col = rand() % maxColor;
			s->setPartitionColor(conflicts[random], col);
			if (DEBUG_LEVEL > 3) {
				cout<<"Recolor node "<<conflicts[random]<<" with color ";
				cout<<col<<endl;
			}

			/// Search for conflicts with the randomly recolored node
			pair<AdjIter, AdjIter> aIter;
			for (aIter = adjacent_vertices(conflicts[random], *s->g);
				  aIter.first != aIter.second; aIter.first++) {

				for (i = 0; i < s->numParts; i++) {
					colors[i] = 0;
				}

				for (ai = adjacent_vertices(*aIter.first, *s->g);
					  ai.first != ai.second; ai.first++) {

					colors[s->getPartitionColor(*ai.first)] = 1;
				}

				/// Try recoloring conflicting nodes
				bool found = false;
				for (i = 0; i < maxColor && !found; i++) {
					if (colors[i] == 0) {
						if (DEBUG_LEVEL > 3) {
							cout<<"Found new suitable color "<<i<<" for Node ";
							cout<<*aIter.first<<endl;
						}
						found = true;
						s->setPartitionColor(*aIter.first, i);
						break;
					}
				}
				/// Conflict could not be resolved
				if (!found) {
					if (DEBUG_LEVEL > 2) {
						cout<<"Conflict could not be resolved for Node ";
						cout<<*aIter.first<<endl;
					}
				}
			}
		}

		/// Rebuild conflicting nodes
		conflicts.clear();
		for (vIter = vertices(*s->g); vIter.first != vIter.second;
			  vIter.first++) {

			for (ai = adjacent_vertices(*vIter.first, *s->g);
				  ai.first != ai.second; ai.first++) {

				if (s->getPartitionColor(*ai.first) ==
					 s->getPartitionColor(*vIter.first)) {

					if (DEBUG_LEVEL > 3) {
						cout<<"Conflicting node "<<*vIter.first<< " with color ";
						cout<<s->partition[vParts[*vIter.first]]<<" added to conflicts";
						cout<<endl;
					}
					conflicts.push_back(*vIter.first);
					break;
				}
			}
		}
	}

	/// New solution is not conflict free, return curBest
	if (conflicts.size() != 0) {
		if (DEBUG_LEVEL > 1) {
			cout<<"Conflict found"<<endl;
		}
		s->colorsUsed = s->numParts;
		return s;
	}

	/// New solution is conflict free, count colorsUsed and return
	else {
		maxColor = 0;
		for (int i = 0; i < s->numParts; i++) {

			if (s->partition[i] > maxColor) {
				maxColor = s->partition[i];
			}
		}
		s->colorsUsed = maxColor + 1;

		if (DEBUG_LEVEL > 1) {
			cout<<"Change Color uses "<<s->colorsUsed<<" colors"<<endl;
		}

		Solution *temp = new Solution(s);
		temp = this->findLocalMin(*temp, full);
		if (temp->colorsUsed < s->colorsUsed) {
			delete s;
			s = temp;
		}
		else
			delete temp;
	}
	return s;
}

/// Reset all colors to unset, then proceed by selecting a node randomly,
/// recolor it with the least possible color. Proceed until all nodes are
/// colored
Solution *changeColor::shuffleSolution(Solution& cur, Solution& full,
				 							  int numSteps) {
	if (DEBUG_LEVEL > 3) {
		cout<<"Shaking with changeColor with"<<endl;
	}

	Solution *ret = &cur;
	vector<Vertex> uncolored;

	/// Reset all colors
	for (int i = 0; i < numSteps; i++) {
		uncolored.push_back(rand() % ret->numParts);
	}

	random_shuffle(uncolored.begin(), uncolored.end());
	/// Proceed until all nodes are colored
	Vertex node = 0;
	int color;
	int maxColor = ret->colorsUsed - 1;
	while (uncolored.size() != 0) {
		node = uncolored.back();
		uncolored.pop_back();
		color = ret->minPossibleColor(node);
		ret->setPartitionColor(node, color);
		if (color > maxColor)
			maxColor = color;
	}
	ret->colorsUsed = maxColor + 1;

	return ret;
}
<|endoftext|>


<commit_before>#include <string.h>
#include <math.h>
#include <iostream>
#include <stdexcept>
#include "FireLog.h"
#include "FireSight.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "jansson.h"
#include "jo_util.hpp"
#include "MatUtil.hpp"
#include "version.h"

using namespace cv;
using namespace std;
using namespace firesight;

enum CompareOp {
    COMPARE_XY,
    COMPARE_YX
};

typedef class ComparePoint2f {
    private:
        CompareOp op;

    public:
        ComparePoint2f(CompareOp op=COMPARE_XY) {
            this->op = op;
        }
    public:
        bool operator()(const Point2f &lhs, const Point2f &rhs) const {
            assert(!isnan(lhs.x));
            assert(!isnan(rhs.x));
            int cmp;
            switch (op) {
            case COMPARE_XY:
                cmp = lhs.x - rhs.x;
                if (cmp == 0) {
                    cmp = lhs.y - rhs.y;
                }
                break;
            case COMPARE_YX:
                cmp = lhs.y - rhs.y;
                if (cmp == 0) {
                    cmp = lhs.x - rhs.x;
                }
                break;
            }
            return cmp < 0;
        }
} ComparePoint2f;

typedef map<Point2f,Point2f,ComparePoint2f> PointMap;

bool Pipeline::apply_matchGrid(json_t *pStage, json_t *pStageModel, Model &model) {
    string rectsModelName = jo_string(pStage, "model", "", model.argMap);
    double sepX = jo_double(pStage, "sepX", 5.0, model.argMap);
    double sepY = jo_double(pStage, "sepY", 5.0, model.argMap);
    double tolerance = jo_double(pStage, "tolerance", 0.35, model.argMap);
    json_t *pRectsModel = json_object_get(model.getJson(false), rectsModelName.c_str());
    string errMsg;

    if (rectsModelName.empty()) {
        errMsg = "matchGrid model: expected name of stage with rects";
    } else if (!json_is_object(pRectsModel)) {
        errMsg = "Named stage is not in model";
    }

    json_t *pRects = NULL;
    if (errMsg.empty()) {
        pRects = json_object_get(pRectsModel, "rects");
        if (!json_is_array(pRects)) {
            errMsg = "Expected array of rects to match";
        } else if (json_array_size(pRects) < 2) {
            errMsg = "Expected array of at least 2 rects to match";
        }
    }

    Point2f dTot1;
    Point2f dTot2;
    int dCount1 = 0;
    int dCount2 = 0;
    float dyMedian = FLT_MAX;
    const ComparePoint2f cmp;
    if (errMsg.empty()) {
        PointMap pointMap(cmp);
        json_t *pValue;
        int index;
        json_array_foreach(pRects, index, pValue) {
            json_t *pX = json_object_get(pValue, "x");
            json_t *pY = json_object_get(pValue, "y");
            if (json_is_number(pX) && json_is_number(pY)) {
                double x = json_real_value(pX);
                double y = json_real_value(pY);
                const Point2f key(x,y);
                cout << "adding " << key << " to pointMap(" << pointMap.size() << ")" << endl;
                pointMap[key] = Point2f(x,y);
            }
        }

        vector<float> listXY;
        Point2f prevPt;
        for (PointMap::iterator it=pointMap.begin(); it!=pointMap.end(); it++) {
            if (it != pointMap.begin()) {
                float dy = prevPt.y - it->first.y;
                listXY.push_back(dy);
            }
            prevPt = it->first;
        }
        sort(listXY.begin(), listXY.end());
        dyMedian = listXY[listXY.size()/2];
        float maxTol = dyMedian < 0 ? 1-tolerance : 1+tolerance;
        float minTol = dyMedian < 0 ? 1+tolerance : 1-tolerance;
        float maxDy1 = dyMedian * maxTol;
        float minDy1 = dyMedian * minTol;
        float maxDy2 = 2*dyMedian * maxTol;
        float minDy2 = 2*dyMedian * minTol;

        Point2f prevPt1;
        Point2f prevPt2;
        int n = 0;
        for (map<Point2f,Point2f,ComparePoint2f>::iterator it=pointMap.begin();
                it!=pointMap.end(); it++) {
            const Point2f &curPt = it->first;
            cout << "(" << curPt.x << "," << curPt.y << ")" << endl;
            if (n > 0) {
                int dy1 = prevPt1.y - curPt.y;
                if (minDy1 <= dy1 && dy1 <= maxDy1) {
                    dTot1 = dTot1 + (prevPt1 - curPt);
                    dCount1++;
                }
                if (n > 1) {
                    int dy2 = prevPt2.y - curPt.y;
                    if (minDy2 <= dy2 && dy2 <= maxDy2) {
                        dTot2 = dTot2 + (prevPt2 - curPt);
                        dCount2++;
                    }
                }
            }
            prevPt2 = prevPt1;
            prevPt1 = curPt;
            n++;
        }
        json_object_set(pStageModel, "dyMedian", json_real(dyMedian));
        json_object_set(pStageModel, "dCount1", json_integer(dCount1));
        json_object_set(pStageModel, "dCount2", json_integer(dCount2));
        if (dCount1 == 0) {
            errMsg = "No grid points matched within tolerance (level 1)";
        } else if (dCount2 == 0) {
            json_object_set(pStageModel, "dxAvg1", json_real(dTot1.x/dCount1));
            json_object_set(pStageModel, "dyAvg1", json_real(dTot1.y/dCount1));
            errMsg = "No grid points matched within tolerance (level 2)";
        } else {
            float dxAvg2 = dTot2.x/dCount2/2;
            float dyAvg2 = dTot2.y/dCount2/2;
            json_object_set(pStageModel, "dxAvg1", json_real(dTot1.x/dCount1));
            json_object_set(pStageModel, "dyAvg1", json_real(dTot1.y/dCount1));
            json_object_set(pStageModel, "dxAvg2", json_real(dxAvg2));
            json_object_set(pStageModel, "dyAvg2", json_real(dyAvg2));
            float gridY = sqrt(dxAvg2*dxAvg2 + dyAvg2*dyAvg2) / sepY;
            float gridX = sqrt(dxAvg2*dxAvg2 + dyAvg2*dyAvg2) / sepX;
            json_object_set(pStageModel, "gridY", json_real(gridY));
            json_object_set(pStageModel, "gridX", json_real(gridX));
        }
    }

    return stageOK("apply_matchGrid(%s) %s", errMsg.c_str(), pStage, pStageModel);
}

<commit_msg>refactor<commit_after>#include <string.h>
#include <math.h>
#include <iostream>
#include <stdexcept>
#include "FireLog.h"
#include "FireSight.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "jansson.h"
#include "jo_util.hpp"
#include "MatUtil.hpp"
#include "version.h"

using namespace cv;
using namespace std;
using namespace firesight;

enum CompareOp {
    COMPARE_XY,
    COMPARE_YX
};

typedef class ComparePoint2f {
    private:
        CompareOp op;

    public:
        ComparePoint2f(CompareOp op=COMPARE_XY) {
            this->op = op;
        }
    public:
        bool operator()(const Point2f &lhs, const Point2f &rhs) const {
            assert(!isnan(lhs.x));
            assert(!isnan(rhs.x));
            int cmp;
            switch (op) {
            case COMPARE_XY:
                cmp = lhs.x - rhs.x;
                if (cmp == 0) {
                    cmp = lhs.y - rhs.y;
                }
                break;
            case COMPARE_YX:
                cmp = lhs.y - rhs.y;
                if (cmp == 0) {
                    cmp = lhs.x - rhs.x;
                }
                break;
            }
            return cmp < 0;
        }
} ComparePoint2f;

typedef map<Point2f,Point2f,ComparePoint2f> PointMap;

bool Pipeline::apply_matchGrid(json_t *pStage, json_t *pStageModel, Model &model) {
    string rectsModelName = jo_string(pStage, "model", "", model.argMap);
    double sepX = jo_double(pStage, "sepX", 5.0, model.argMap);
    double sepY = jo_double(pStage, "sepY", 5.0, model.argMap);
    double tolerance = jo_double(pStage, "tolerance", 0.35, model.argMap);
    json_t *pRectsModel = json_object_get(model.getJson(false), rectsModelName.c_str());
    string errMsg;

    if (rectsModelName.empty()) {
        errMsg = "matchGrid model: expected name of stage with rects";
    } else if (!json_is_object(pRectsModel)) {
        errMsg = "Named stage is not in model";
    }

    json_t *pRects = NULL;
    if (errMsg.empty()) {
        pRects = json_object_get(pRectsModel, "rects");
        if (!json_is_array(pRects)) {
            errMsg = "Expected array of rects to match";
        } else if (json_array_size(pRects) < 2) {
            errMsg = "Expected array of at least 2 rects to match";
        }
    }

    Point2f dTot1;
    Point2f dTot2;
    int dCount1 = 0;
    int dCount2 = 0;
    float dyMedian = FLT_MAX;
    const ComparePoint2f cmpXY(COMPARE_XY);
    const ComparePoint2f cmpYX(COMPARE_YX);
    if (errMsg.empty()) {
        PointMap pointMapXY(cmpXY);
        PointMap pointMapYX(cmpYX);
        json_t *pValue;
        int index;
        json_array_foreach(pRects, index, pValue) {
            json_t *pX = json_object_get(pValue, "x");
            json_t *pY = json_object_get(pValue, "y");
            if (json_is_number(pX) && json_is_number(pY)) {
                double x = json_real_value(pX);
                double y = json_real_value(pY);
                const Point2f key(x,y);
                cout << "adding " << key << " to pointMapXY(" << pointMapXY.size() << ")" << endl;
                pointMapXY[key] = Point2f(x,y);
                cout << "adding " << key << " to pointMapYX(" << pointMapYX.size() << ")" << endl;
                pointMapYX[key] = Point2f(x,y);
            }
        }

        vector<float> dyList;
        vector<float> dxList;
        Point2f prevPt;
        for (PointMap::iterator it=pointMapXY.begin(); it!=pointMapXY.end(); it++) {
            if (it != pointMapXY.begin()) {
                float dy = prevPt.y - it->first.y;
                dyList.push_back(dy);
				float dx = prevPt.x - it->first.x;
                dxList.push_back(dx);
            }
            prevPt = it->first;
        }
        sort(dyList.begin(), dyList.end());
        sort(dxList.begin(), dxList.end());
        dyMedian = dyList[dyList.size()/2];
        float maxTol = dyMedian < 0 ? 1-tolerance : 1+tolerance;
        float minTol = dyMedian < 0 ? 1+tolerance : 1-tolerance;
        float maxDy1 = dyMedian * maxTol;
        float minDy1 = dyMedian * minTol;
        float maxDy2 = 2*dyMedian * maxTol;
        float minDy2 = 2*dyMedian * minTol;

        Point2f prevPt1;
        Point2f prevPt2;
        int n = 0;
        for (map<Point2f,Point2f,ComparePoint2f>::iterator it=pointMapXY.begin();
                it!=pointMapXY.end(); it++) {
            const Point2f &curPt = it->first;
            cout << "(" << curPt.x << "," << curPt.y << ")" << endl;
            if (n > 0) {
                int dy1 = prevPt1.y - curPt.y;
                if (minDy1 <= dy1 && dy1 <= maxDy1) {
                    dTot1 = dTot1 + (prevPt1 - curPt);
                    dCount1++;
                }
                if (n > 1) {
                    int dy2 = prevPt2.y - curPt.y;
                    if (minDy2 <= dy2 && dy2 <= maxDy2) {
                        dTot2 = dTot2 + (prevPt2 - curPt);
                        dCount2++;
                    }
                }
            }
            prevPt2 = prevPt1;
            prevPt1 = curPt;
            n++;
        }
        json_object_set(pStageModel, "dyMedian", json_real(dyMedian));
        json_object_set(pStageModel, "dCount1", json_integer(dCount1));
        json_object_set(pStageModel, "dCount2", json_integer(dCount2));
        if (dCount1 == 0) {
            errMsg = "No grid points matched within tolerance (level 1)";
        } else if (dCount2 == 0) {
            json_object_set(pStageModel, "dxAvg1", json_real(dTot1.x/dCount1));
            json_object_set(pStageModel, "dyAvg1", json_real(dTot1.y/dCount1));
            errMsg = "No grid points matched within tolerance (level 2)";
        } else {
            float dxAvg2 = dTot2.x/dCount2/2;
            float dyAvg2 = dTot2.y/dCount2/2;
            json_object_set(pStageModel, "dxAvg1", json_real(dTot1.x/dCount1));
            json_object_set(pStageModel, "dyAvg1", json_real(dTot1.y/dCount1));
            json_object_set(pStageModel, "dxAvg2", json_real(dxAvg2));
            json_object_set(pStageModel, "dyAvg2", json_real(dyAvg2));
            float gridY = sqrt(dxAvg2*dxAvg2 + dyAvg2*dyAvg2) / sepY;
            float gridX = sqrt(dxAvg2*dxAvg2 + dyAvg2*dyAvg2) / sepX;
            json_object_set(pStageModel, "gridY", json_real(gridY));
            json_object_set(pStageModel, "gridX", json_real(gridX));
        }
    }

    return stageOK("apply_matchGrid(%s) %s", errMsg.c_str(), pStage, pStageModel);
}

<|endoftext|>