<commit_before>#include "LARA2GUN.H"

#include "SPECIFIC.H"
#include "LARA.H"
#include "LARAFIRE.H"
#ifdef PC_VERSION
#include "GAME.H"
#else
#include "SETUP.H"
#endif
#include "DRAW.H"
#include "OBJECTS.H"
#include "EFFECTS.H"
#include "SOUND.H"

static struct PISTOL_DEF PistolTable[4] =
{
	{ LARA, 0, 0, 0, 0 },
	{ PISTOLS_ANIM, 4, 5, 0xD, 0x18 },
	{ REVOLVER_ANIM , 7, 8, 0xF, 0x1D },
	{ UZI_ANIM, 4, 5, 0xD, 0x18 }
};

void AnimatePistols(int weapon_type)
{
	UNIMPLEMENTED();
}

void PistolHandler(int weapon_type)
{
	UNIMPLEMENTED();
}

void undraw_pistol_mesh_right(int weapon_type)//44968(<), 44DCC(<) (F)
{
	WeaponObject(weapon_type);
	lara.mesh_ptrs[LM_RHAND] = meshes[objects[LARA].mesh_index + 2 * LM_RHAND];
	switch (weapon_type)
	{
	case WEAPON_PISTOLS:
		lara.holster = LARA_HOLSTERS_PISTOLS;
		break;
	case WEAPON_REVOLVER:
		lara.holster = LARA_HOLSTERS_REVOLVER;
		break;
	case WEAPON_UZI:
		lara.holster = LARA_HOLSTERS_UZIS;
		break;
	}
}

void undraw_pistol_mesh_left(int weapon_type)//448F0(<), 44D54(<) (F)
{
	if(weapon_type != WEAPON_REVOLVER)
	{
		WeaponObject(weapon_type);
		lara.mesh_ptrs[LM_LHAND] = meshes[objects[LARA].mesh_index + 2 * LM_LHAND];
		switch (weapon_type)
		{
		case WEAPON_PISTOLS:
			lara.holster = LARA_HOLSTERS_PISTOLS;
			break;
		case WEAPON_UZI:
			lara.holster = LARA_HOLSTERS_UZIS;
			break;
		}
	}
}

void draw_pistol_meshes(int weapon_type)// (F)
{
	lara.holster = LARA_HOLSTERS;
	lara.mesh_ptrs[LM_RHAND] = meshes[objects[WeaponObjectMesh(weapon_type)].mesh_index + 2 * LM_RHAND];

	if (weapon_type != WEAPON_REVOLVER)
	{
		lara.mesh_ptrs[LM_LHAND] = meshes[objects[WeaponObjectMesh(weapon_type)].mesh_index + 2 * LM_LHAND];
	}
}

void ready_pistols(int weapon_type)// (F)
{
	lara.gun_status = LG_READY;
	lara.left_arm.z_rot = 0;
	lara.left_arm.y_rot = 0;
	lara.left_arm.x_rot = 0;
	lara.right_arm.z_rot = 0;
	lara.right_arm.y_rot = 0;
	lara.right_arm.x_rot = 0;
	lara.right_arm.frame_number = 0;
	lara.left_arm.frame_number = 0;
	lara.target = 0;
	lara.right_arm.lock = 0;
	lara.left_arm.lock = 0;
	lara.right_arm.frame_base = lara.left_arm.frame_base = objects[WeaponObject(weapon_type)].frame_base;
}

void undraw_pistols(int weapon_type)
{
	UNIMPLEMENTED();
}

void draw_pistols(int weapon_type)// (F)
{
	struct PISTOL_DEF* p = &PistolTable[lara.gun_type];
	short ani = lara.left_arm.frame_number + 1;

	if (ani < p->Draw1Anim || ani > p->RecoilAnim - 1)
	{
		ani = p->Draw1Anim;
	}
	else if (ani == p->Draw2Anim)
	{
		draw_pistol_meshes(weapon_type);
		SoundEffect(SFX_LARA_HOLSTER_DRAW, &lara_item->pos, SFX_DEFAULT);
	}
	else if (ani == p->RecoilAnim - 1)
	{
		ready_pistols(weapon_type);
		ani = 0;
	}

	set_arm_info(&lara.right_arm, ani);
	set_arm_info(&lara.left_arm, ani);
}

void set_arm_info(struct lara_arm* arm, int frame)// (F)
{
	struct PISTOL_DEF* def = &PistolTable[lara.gun_type];
	int anim_base = objects[def->ObjectNum].anim_index;

	if (frame >= def->Draw1Anim)
	{
		if (frame >= def->Draw2Anim)
		{
			if (frame >= def->RecoilAnim)
			{
				anim_base += 3;
			}
			else
			{
				anim_base += 2;
			}
		}
		else
		{
			anim_base += 1;
		}
	}

	arm->anim_number = anim_base;
	arm->frame_number = frame;
	arm->frame_base = anims[anim_base].frame_ptr;
}<commit_msg>[Specific-PSXPC_N] Correct draw_pistols.<commit_after>#include "LARA2GUN.H"

#include "SPECIFIC.H"
#include "LARA.H"
#include "LARAFIRE.H"
#ifdef PC_VERSION
#include "GAME.H"
#else
#include "SETUP.H"
#endif
#include "DRAW.H"
#include "OBJECTS.H"
#include "EFFECTS.H"
#include "SOUND.H"

static struct PISTOL_DEF PistolTable[4] =
{
	{ LARA, 0, 0, 0, 0 },
	{ PISTOLS_ANIM, 4, 5, 0xD, 0x18 },
	{ REVOLVER_ANIM , 7, 8, 0xF, 0x1D },
	{ UZI_ANIM, 4, 5, 0xD, 0x18 }
};

void AnimatePistols(int weapon_type)
{
	UNIMPLEMENTED();
}

void PistolHandler(int weapon_type)
{
	UNIMPLEMENTED();
}

void undraw_pistol_mesh_right(int weapon_type)//44968(<), 44DCC(<) (F)
{
	WeaponObject(weapon_type);
	lara.mesh_ptrs[LM_RHAND] = meshes[objects[LARA].mesh_index + 2 * LM_RHAND];
	switch (weapon_type)
	{
	case WEAPON_PISTOLS:
		lara.holster = LARA_HOLSTERS_PISTOLS;
		break;
	case WEAPON_REVOLVER:
		lara.holster = LARA_HOLSTERS_REVOLVER;
		break;
	case WEAPON_UZI:
		lara.holster = LARA_HOLSTERS_UZIS;
		break;
	}
}

void undraw_pistol_mesh_left(int weapon_type)//448F0(<), 44D54(<) (F)
{
	if(weapon_type != WEAPON_REVOLVER)
	{
		WeaponObject(weapon_type);
		lara.mesh_ptrs[LM_LHAND] = meshes[objects[LARA].mesh_index + 2 * LM_LHAND];
		switch (weapon_type)
		{
		case WEAPON_PISTOLS:
			lara.holster = LARA_HOLSTERS_PISTOLS;
			break;
		case WEAPON_UZI:
			lara.holster = LARA_HOLSTERS_UZIS;
			break;
		}
	}
}

void draw_pistol_meshes(int weapon_type)// (F)
{
	lara.holster = LARA_HOLSTERS;
	lara.mesh_ptrs[LM_RHAND] = meshes[objects[WeaponObjectMesh(weapon_type)].mesh_index + 2 * LM_RHAND];

	if (weapon_type != WEAPON_REVOLVER)
	{
		lara.mesh_ptrs[LM_LHAND] = meshes[objects[WeaponObjectMesh(weapon_type)].mesh_index + 2 * LM_LHAND];
	}
}

void ready_pistols(int weapon_type)// (F)
{
	lara.gun_status = LG_READY;
	lara.left_arm.z_rot = 0;
	lara.left_arm.y_rot = 0;
	lara.left_arm.x_rot = 0;
	lara.right_arm.z_rot = 0;
	lara.right_arm.y_rot = 0;
	lara.right_arm.x_rot = 0;
	lara.right_arm.frame_number = 0;
	lara.left_arm.frame_number = 0;
	lara.target = 0;
	lara.right_arm.lock = 0;
	lara.left_arm.lock = 0;
	lara.right_arm.frame_base = lara.left_arm.frame_base = objects[WeaponObject(weapon_type)].frame_base;
}

void undraw_pistols(int weapon_type)//
{
	UNIMPLEMENTED();
}

void draw_pistols(int weapon_type)//443B4, 44818 (F)
{
	struct PISTOL_DEF* p = &PistolTable[lara.gun_type];//$a1
	short ani = lara.left_arm.frame_number + 1;//$s1

	//a3 = p->Draw1Anim

	//v0 = p->RecoilAnim
	if (ani < p->Draw1Anim || p->RecoilAnim - 1 < ani)
	{
		//loc_44420
		ani = p->Draw1Anim;
	}
	else
	{

		//loc_44428
		if (ani == p->Draw2Anim)
		{
			draw_pistol_meshes(weapon_type);
			//a1 = lara_item
			//a0 = 6
			//a2 = 0;
			SoundEffect(SFX_LARA_HOLSTER_DRAW, &lara_item->pos, 0);
			//s0 = &lara.right_arm.frame_base
		}//loc_44460
		else if (ani == p->RecoilAnim - 1)
		{
			ready_pistols(weapon_type);
			ani = 0;
		}
	}

	set_arm_info(&lara.right_arm, ani);
	set_arm_info(&lara.left_arm, ani);
}

void set_arm_info(struct lara_arm* arm, int frame)// (F)
{
	struct PISTOL_DEF* def = &PistolTable[lara.gun_type];
	int anim_base = objects[def->ObjectNum].anim_index;

	if (frame >= def->Draw1Anim)
	{
		if (frame >= def->Draw2Anim)
		{
			if (frame >= def->RecoilAnim)
			{
				anim_base += 3;
			}
			else
			{
				anim_base += 2;
			}
		}
		else
		{
			anim_base += 1;
		}
	}

	arm->anim_number = anim_base;
	arm->frame_number = frame;
	arm->frame_base = anims[anim_base].frame_ptr;
}<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#include <boost/python.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

#include <mapnik/rule.hpp>
#include <mapnik/filter_factory.hpp>

using namespace boost::python;
using mapnik::rule_type;
using mapnik::filter;
using mapnik::filter_ptr;
using mapnik::filter_factory;
using mapnik::Feature;
using mapnik::point_symbolizer;
using mapnik::line_symbolizer;
using mapnik::line_pattern_symbolizer;
using mapnik::polygon_symbolizer;
using mapnik::polygon_pattern_symbolizer;
using mapnik::raster_symbolizer;
using mapnik::shield_symbolizer;
using mapnik::text_symbolizer;
using mapnik::building_symbolizer;
using mapnik::symbolizer;
using mapnik::symbolizers;

struct rule_pickle_suite : boost::python::pickle_suite
{
   static boost::python::tuple
   getinitargs(const rule_type& r)
   {
      return boost::python::make_tuple(r.get_name(),r.get_title(),r.get_min_scale(),r.get_max_scale());
   }

   static  boost::python::tuple
   getstate(const rule_type& r)
   {
        boost::python::list syms;
        symbolizers::const_iterator it = r.begin();
        symbolizers::const_iterator end = r.end();
        for (; it != end; ++it)
        {
            syms.append( *it );
        }

        // Here the filter string is used rather than the actual Filter object
        // Need to look into how to get the Filter object
        std::string filter_expr = r.get_filter()->to_string();
        return boost::python::make_tuple(r.get_abstract(),filter_expr,r.has_else_filter(),syms);
   }

   static void
   setstate (rule_type& r, boost::python::tuple state)
   {
        using namespace boost::python;
        if (len(state) != 4)
        {
            PyErr_SetObject(PyExc_ValueError,
                         ("expected 4-item tuple in call to __setstate__; got %s"
                          % state).ptr()
            );
            throw_error_already_set();
        }

        if (state[0])
        {
            r.set_title(extract<std::string>(state[0]));
        }

        if (state[1])
        {
            std::string filter_expr=extract<std::string>(state[1]);
            r.set_filter(mapnik::create_filter(filter_expr,"utf8"));
        }

        if (state[2])
        {
            r.set_else(true);
        }

        boost::python::list syms=extract<boost::python::list>(state[3]);
        for (int i=0;i<len(syms);++i)
        {
            r.append(extract<symbolizer>(syms[i]));
        }

   }

};

void export_rule()
{

    implicitly_convertible<point_symbolizer,symbolizer>();
    implicitly_convertible<line_symbolizer,symbolizer>();
    implicitly_convertible<line_pattern_symbolizer,symbolizer>();
    implicitly_convertible<polygon_symbolizer,symbolizer>();
    implicitly_convertible<building_symbolizer,symbolizer>();
    implicitly_convertible<polygon_pattern_symbolizer,symbolizer>();
    implicitly_convertible<raster_symbolizer,symbolizer>();
    implicitly_convertible<shield_symbolizer,symbolizer>();
    implicitly_convertible<text_symbolizer,symbolizer>();

    class_<symbolizers>("Symbolizers",init<>("TODO"))
    	.def(vector_indexing_suite<symbolizers>())
    	;

    class_<rule_type>("Rule",init<>("default constructor"))
        .def(init<std::string const&,
             boost::python::optional<std::string const&,double,double> >())
        .def_pickle(rule_pickle_suite()
           )
        .add_property("name",make_function
                      (&rule_type::get_name,
                       return_value_policy<copy_const_reference>()),
                      &rule_type::set_name)
        .add_property("title",make_function
                      (&rule_type::get_title,return_value_policy<copy_const_reference>()),
                      &rule_type::set_title)
        .add_property("abstract",make_function
                      (&rule_type::get_abstract,return_value_policy<copy_const_reference>()),
                      &rule_type::set_abstract)
        .add_property("filter",make_function
                      (&rule_type::get_filter,return_value_policy<copy_const_reference>()),
                      &rule_type::set_filter)
        .add_property("min_scale",&rule_type::get_min_scale,&rule_type::set_min_scale)
        .add_property("max_scale",&rule_type::get_max_scale,&rule_type::set_max_scale)
        .def("set_else",&rule_type::set_else)
        .def("has_else",&rule_type::has_else_filter)
        .def("active",&rule_type::active)
        .add_property("symbols",make_function
                      (&rule_type::get_symbolizers,return_value_policy<reference_existing_object>()))
        ;
}

<commit_msg>move the boost::python namespace back to original location<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#include <boost/python.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

#include <mapnik/rule.hpp>
#include <mapnik/filter_factory.hpp>

using mapnik::rule_type;
using mapnik::filter;
using mapnik::filter_ptr;
using mapnik::filter_factory;
using mapnik::Feature;
using mapnik::point_symbolizer;
using mapnik::line_symbolizer;
using mapnik::line_pattern_symbolizer;
using mapnik::polygon_symbolizer;
using mapnik::polygon_pattern_symbolizer;
using mapnik::raster_symbolizer;
using mapnik::shield_symbolizer;
using mapnik::text_symbolizer;
using mapnik::building_symbolizer;
using mapnik::symbolizer;
using mapnik::symbolizers;

struct rule_pickle_suite : boost::python::pickle_suite
{
   static boost::python::tuple
   getinitargs(const rule_type& r)
   {
      return boost::python::make_tuple(r.get_name(),r.get_title(),r.get_min_scale(),r.get_max_scale());
   }

   static  boost::python::tuple
   getstate(const rule_type& r)
   {
        boost::python::list syms;
        symbolizers::const_iterator it = r.begin();
        symbolizers::const_iterator end = r.end();
        for (; it != end; ++it)
        {
            syms.append( *it );
        }

        // Here the filter string is used rather than the actual Filter object
        // Need to look into how to get the Filter object
        std::string filter_expr = r.get_filter()->to_string();
        return boost::python::make_tuple(r.get_abstract(),filter_expr,r.has_else_filter(),syms);
   }

   static void
   setstate (rule_type& r, boost::python::tuple state)
   {
        using namespace boost::python;
        if (len(state) != 4)
        {
            PyErr_SetObject(PyExc_ValueError,
                         ("expected 4-item tuple in call to __setstate__; got %s"
                          % state).ptr()
            );
            throw_error_already_set();
        }

        if (state[0])
        {
            r.set_title(extract<std::string>(state[0]));
        }

        if (state[1])
        {
            std::string filter_expr=extract<std::string>(state[1]);
            r.set_filter(mapnik::create_filter(filter_expr,"utf8"));
        }

        if (state[2])
        {
            r.set_else(true);
        }

        boost::python::list syms=extract<boost::python::list>(state[3]);
        for (int i=0;i<len(syms);++i)
        {
            r.append(extract<symbolizer>(syms[i]));
        }

   }

};

void export_rule()
{
    using namespace boost::python;
    implicitly_convertible<point_symbolizer,symbolizer>();
    implicitly_convertible<line_symbolizer,symbolizer>();
    implicitly_convertible<line_pattern_symbolizer,symbolizer>();
    implicitly_convertible<polygon_symbolizer,symbolizer>();
    implicitly_convertible<building_symbolizer,symbolizer>();
    implicitly_convertible<polygon_pattern_symbolizer,symbolizer>();
    implicitly_convertible<raster_symbolizer,symbolizer>();
    implicitly_convertible<shield_symbolizer,symbolizer>();
    implicitly_convertible<text_symbolizer,symbolizer>();

    class_<symbolizers>("Symbolizers",init<>("TODO"))
    	.def(vector_indexing_suite<symbolizers>())
    	;

    class_<rule_type>("Rule",init<>("default constructor"))
        .def(init<std::string const&,
             boost::python::optional<std::string const&,double,double> >())
        .def_pickle(rule_pickle_suite()
           )
        .add_property("name",make_function
                      (&rule_type::get_name,
                       return_value_policy<copy_const_reference>()),
                      &rule_type::set_name)
        .add_property("title",make_function
                      (&rule_type::get_title,return_value_policy<copy_const_reference>()),
                      &rule_type::set_title)
        .add_property("abstract",make_function
                      (&rule_type::get_abstract,return_value_policy<copy_const_reference>()),
                      &rule_type::set_abstract)
        .add_property("filter",make_function
                      (&rule_type::get_filter,return_value_policy<copy_const_reference>()),
                      &rule_type::set_filter)
        .add_property("min_scale",&rule_type::get_min_scale,&rule_type::set_min_scale)
        .add_property("max_scale",&rule_type::get_max_scale,&rule_type::set_max_scale)
        .def("set_else",&rule_type::set_else)
        .def("has_else",&rule_type::has_else_filter)
        .def("active",&rule_type::active)
        .add_property("symbols",make_function
                      (&rule_type::get_symbolizers,return_value_policy<reference_existing_object>()))
        ;
}

<|endoftext|>


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

#ifndef ARY_STDCONSTITER_HXX
#define ARY_STDCONSTITER_HXX
//  KORR_DEPRECATED_3.0

// USED SERVICES
    // BASE CLASSES
    // COMPONENTS
    // PARAMETERS

namespace ary
{

template <class ELEM>

class StdConstIterator
{
  public:
    virtual             ~StdConstIterator() {}

    void                operator++()            { do_Advance(); }
    const ELEM &        operator*() const       { return *inq_CurElement(); }
                        operator bool() const   { return inq_CurElement() != 0; }

    /// Needed as replacement for operator bool() in gcc 2.95.
    bool                IsValid() const         { return operator bool(); }
    bool                IsSorted() const        { return inq_IsSorted(); }

  protected:
                        StdConstIterator() {}

  private:
    //Locals
    virtual void        do_Advance() = 0;
    virtual const ELEM *
                        inq_CurElement() const = 0;
    virtual bool        inq_IsSorted() const = 0;

    // Forbidden:
    StdConstIterator(const StdConstIterator<ELEM>&);
    StdConstIterator<ELEM> & operator=(const StdConstIterator<ELEM>&);
};

template <class ELEM>
class Dyn_StdConstIterator
{
  public:
    typedef StdConstIterator<ELEM> client_type;

                        Dyn_StdConstIterator(
                            DYN client_type *   pass_dpIterator = 0 )
                                                : pClient(pass_dpIterator) {}
    Dyn_StdConstIterator<ELEM> &
                        operator=(
                            DYN client_type *   pass_dpIterator )
                                                { pClient = pass_dpIterator;
                                                  return *this; }
    client_type &       operator*() const       { return *pClient.MutablePtr(); }

  private:
    Dyn<client_type>    pClient;
};

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

#ifndef ARY_STDCONSTITER_HXX
#define ARY_STDCONSTITER_HXX
//  KORR_DEPRECATED_3.0

// USED SERVICES
    // BASE CLASSES
    // COMPONENTS
    // PARAMETERS

namespace ary
{

template <class ELEM>

class StdConstIterator
{
  public:
    virtual             ~StdConstIterator() {}

    void                operator++()            { do_Advance(); }
    const ELEM &        operator*() const       { return *inq_CurElement(); }
                        operator bool() const   { return inq_CurElement() != 0; }

    /// Needed as replacement for operator bool() in gcc 2.95.
    bool                IsValid() const         { return operator bool(); }
    bool                IsSorted() const        { return inq_IsSorted(); }

  protected:
                        StdConstIterator() {}

  private:
    //Locals
    virtual void        do_Advance() = 0;
    virtual const ELEM *
                        inq_CurElement() const = 0;
    virtual bool        inq_IsSorted() const = 0;

    // Forbidden:
    StdConstIterator(const StdConstIterator<ELEM>&);
    StdConstIterator<ELEM> & operator=(const StdConstIterator<ELEM>&);
};

template <class ELEM>
class Dyn_StdConstIterator
{
  public:
    typedef StdConstIterator<ELEM> client_type;

                        Dyn_StdConstIterator(
                            DYN client_type *   pass_dpIterator = 0 )
                                                : pClient(pass_dpIterator) {}
    Dyn_StdConstIterator<ELEM> &
                        operator=(
                            DYN client_type *   pass_dpIterator )
                                                { pClient = pass_dpIterator;
                                                  return *this; }
    client_type &       operator*() const       { return *pClient.MutablePtr(); }

  private:
    Dyn<client_type>    pClient;
};

}   // namespace ary
#endif
<|endoftext|>


<commit_before>#include "GameProcess.h"
#include "Object.h"
#include "Engine.h"
#include "World.h"
#include "App.h"
#include "ToolsCamera.h"
#include "ControlsApp.h"
#include "MathLib.h"
#include "Game.h"
#include "Editor.h"
#include "Input.h"
#include "BlueRayUtils.h"
#include "World.h"

using namespace MathLib;

CGameProcess::CGameProcess(void)
{

}

CGameProcess::~CGameProcess(void)
{

}
int CGameProcess::Init()
{
	g_Engine.pFileSystem->CacheFilesFormExt("char");
	g_Engine.pFileSystem->CacheFilesFormExt("node");
	g_Engine.pFileSystem->CacheFilesFormExt("smesh");
	g_Engine.pFileSystem->CacheFilesFormExt("sanim");

	g_Engine.pWorld->LoadWorld("data/scene/terrain/test/test.world");
	//g_Engine.pWorld->LoadWorld("data/scene/terrain/cj/cj.world");
	g_Engine.pControls->SetKeyPressFunc(KeyPress);
	g_Engine.pControls->SetKeyReleaseFunc(KeyRelease);

	m_pRole = new CFPSRoleLocal();
	m_pRole->Init(10001, "data/role/hero/FpsRole/fps.char");		//ؽɫԴ

	m_pRole->SetActorPosition(vec3(0, 0, 0));	//ýɫʼλáŴΪԭ㣬άϵvec3
	m_pSkillSystem = new CSkillSystem(this);
	m_pCameraBase = new CCameraBase();
	m_pCameraBase->SetEnabled(1);
	g_pSysControl->SetMouseGrab(1);

	m_pStarControl = new CStarControl();
	m_pRayControl = new CRayControl();

	return 1;
}

int CGameProcess::ShutDown()			//رϷ
{
	delete m_pRole;
	delete m_pSkillSystem;
	delete m_pCameraBase;
	delete m_pStarControl;
	delete m_pRayControl;

	DelAllListen();
	return 0;
}

int CGameProcess::Update()
{
	float ifps = g_Engine.pGame->GetIFps();

	if (g_Engine.pInput->IsKeyDown('1'))
	{
		CAction* pAction = m_pRole->OrceAction("attack02");
		if (pAction)
		{
			pAction->SetupSkillThrow(vec3_zero, -1.0f, 2.0f);
			m_pRole->StopMove();
		}
	}
	else if (g_Engine.pInput->IsKeyDown('2'))
	{
		CAction* pAction = m_pRole->OrceAction("skill01");
		if (pAction)
		{
			m_pRole->StopMove();
		}
	}
	else if (g_Engine.pInput->IsKeyDown('3'))
	{
		CAction* pAction = m_pRole->OrceAction("skill02");
		if (pAction)
		{
			m_pRole->StopMove();
			CRoleBase* pTarget = NULL;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 15.0f)
				{
					pTarget = m_vAIList[i];
					break;
				}
			}
			if (pTarget)
			{
				CVector<int> vTarget;
				vTarget.Append(pTarget->GetRoleID());
				pAction->SetupSkillBulletTarget(vTarget);
				m_pRole->SetDirection((pTarget->GetPosition() - m_pRole->GetPosition()).normalize(), 1);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('4'))//෢ӵ
	{
		CAction* pAction = m_pRole->OrceAction("skill02");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<int> vTarget;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
				{
					vTarget.Append(m_vAIList[i]->GetRoleID());
				}
			}
			if (!vTarget.Empty())
			{
				pAction->SetupSkillBulletTarget(vTarget);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('5'))
	{
		CAction* pAction = m_pRole->OrceAction("skill03");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;
			pAction->SetupSkillTargetPoint(vPos);
		}
	}
	else if (g_Engine.pInput->IsKeyDown('6'))
	{
		CAction* pAction = m_pRole->OrceAction("skill06");
		if ()
		{

		}
	}
	return 0;
}

<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "GameProcess.h"
#include "Object.h"
#include "Engine.h"
#include "World.h"
#include "App.h"
#include "ToolsCamera.h"
#include "ControlsApp.h"
#include "MathLib.h"
#include "Game.h"
#include "Editor.h"
#include "Input.h"
#include "BlueRayUtils.h"
#include "World.h"

using namespace MathLib;

CGameProcess::CGameProcess(void)
{

}

CGameProcess::~CGameProcess(void)
{

}
int CGameProcess::Init()
{
	g_Engine.pFileSystem->CacheFilesFormExt("char");
	g_Engine.pFileSystem->CacheFilesFormExt("node");
	g_Engine.pFileSystem->CacheFilesFormExt("smesh");
	g_Engine.pFileSystem->CacheFilesFormExt("sanim");

	g_Engine.pWorld->LoadWorld("data/scene/terrain/test/test.world");
	//g_Engine.pWorld->LoadWorld("data/scene/terrain/cj/cj.world");
	g_Engine.pControls->SetKeyPressFunc(KeyPress);
	g_Engine.pControls->SetKeyReleaseFunc(KeyRelease);

	m_pRole = new CFPSRoleLocal();
	m_pRole->Init(10001, "data/role/hero/FpsRole/fps.char");		//ؽɫԴ

	m_pRole->SetActorPosition(vec3(0, 0, 0));	//ýɫʼλáŴΪԭ㣬άϵvec3
	m_pSkillSystem = new CSkillSystem(this);
	m_pCameraBase = new CCameraBase();
	m_pCameraBase->SetEnabled(1);
	g_pSysControl->SetMouseGrab(1);

	m_pStarControl = new CStarControl();
	m_pRayControl = new CRayControl();

	return 1;
}

int CGameProcess::ShutDown()			//رϷ
{
	delete m_pRole;
	delete m_pSkillSystem;
	delete m_pCameraBase;
	delete m_pStarControl;
	delete m_pRayControl;

	DelAllListen();
	return 0;
}

int CGameProcess::Update()
{
	float ifps = g_Engine.pGame->GetIFps();

	if (g_Engine.pInput->IsKeyDown('1'))
	{
		CAction* pAction = m_pRole->OrceAction("attack02");
		if (pAction)
		{
			pAction->SetupSkillThrow(vec3_zero, -1.0f, 2.0f);
			m_pRole->StopMove();
		}
	}
	else if (g_Engine.pInput->IsKeyDown('2'))
	{
		CAction* pAction = m_pRole->OrceAction("skill01");
		if (pAction)
		{
			m_pRole->StopMove();
		}
	}
	else if (g_Engine.pInput->IsKeyDown('3'))
	{
		CAction* pAction = m_pRole->OrceAction("skill02");
		if (pAction)
		{
			m_pRole->StopMove();
			CRoleBase* pTarget = NULL;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 15.0f)
				{
					pTarget = m_vAIList[i];
					break;
				}
			}
			if (pTarget)
			{
				CVector<int> vTarget;
				vTarget.Append(pTarget->GetRoleID());
				pAction->SetupSkillBulletTarget(vTarget);
				m_pRole->SetDirection((pTarget->GetPosition() - m_pRole->GetPosition()).normalize(), 1);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('4'))//෢ӵ
	{
		CAction* pAction = m_pRole->OrceAction("skill02");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<int> vTarget;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
				{
					vTarget.Append(m_vAIList[i]->GetRoleID());
				}
			}
			if (!vTarget.Empty())
			{
				pAction->SetupSkillBulletTarget(vTarget);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('5'))
	{
		CAction* pAction = m_pRole->OrceAction("skill03");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;
			pAction->SetupSkillTargetPoint(vPos);
		}
	}
	else if (g_Engine.pInput->IsKeyDown('6'))
	{
		CAction* pAction = m_pRole->OrceAction("skill06");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;

		}
	}
	return 0;
}

<|endoftext|>


<commit_before>#include "info.h"
#include <algorithm>

Info::Info() :
    n_parameters_(0),
    n_parameters_to_fit_(0),
    max_chunk_size_(0),
    max_n_iterations_(0),
    n_points_(0),
    power_of_two_n_points_(0),
    n_fits_(0),
    user_info_size_(0),
    n_fits_per_block_(0),
    n_blocks_per_fit_(0),
    model_id_(0),
    estimator_id_(0),
    max_threads_(0),
    max_blocks_(0),
    available_gpu_memory_(0)
{
}

Info::~Info(void)
{
}

void Info::set_number_of_parameters_to_fit(int const * const parameters_to_fit)
{
    n_parameters_to_fit_ = n_parameters_;

    for (int i = 0; i < n_parameters_; i++)
    {
        if (!parameters_to_fit[i])
        {
            n_parameters_to_fit_--;
        }
    }
}

void Info::set_fits_per_block(std::size_t const current_chunk_size)
{
    n_fits_per_block_ = 1;

    if (n_points_ < max_threads_ / 4)
    {
        n_fits_per_block_ = 8;
        bool is_divisible = false;
        bool enough_threads = false;
        do
        {
            n_fits_per_block_ /= 2;
            is_divisible = current_chunk_size % n_fits_per_block_ == 0;
            enough_threads = n_fits_per_block_ * n_points_ < max_threads_ / 4;
        } while ((!is_divisible || !enough_threads) && n_fits_per_block_ > 1);
    }
}

void Info::set_blocks_per_fit()
{
    n_blocks_per_fit_ = 1;

    if (power_of_two_n_points_ > max_threads_)
    {
        bool enough_threads = false;
        do
        {
            n_blocks_per_fit_ *= 2;
            enough_threads = power_of_two_n_points_ / n_blocks_per_fit_ < max_threads_;
        } while (!enough_threads);
    }
}

void Info::set_max_chunk_size()
{
    int one_fit_memory
        = sizeof(float)
        *(2 * n_points_                                     // data, values
        + 2 * n_parameters_                                 // parameters, prev_parameters
        + 1 * n_blocks_per_fit_                             // chi_square
        + 1 * n_parameters_to_fit_ * n_blocks_per_fit_      // gradient
        + 1 * n_parameters_to_fit_ * n_parameters_to_fit_   // hessian
        + 1 * n_parameters_to_fit_                          // delta
        + 1 * n_points_*n_parameters_                       // derivatives
        + 2)                                                // prev_chi_square, lambda
        + sizeof(int)
        * 4;                                                // state, finished, iteration_failed, n_iterations

    if (use_weights_)
        one_fit_memory += sizeof(float) * n_points_;

    std::size_t tmp_chunk_size = available_gpu_memory_ / one_fit_memory;

    if (tmp_chunk_size == 0)
    {
        throw std::runtime_error("not enough free GPU memory available");
    }

    tmp_chunk_size = (std::min)(tmp_chunk_size, max_blocks_ / n_blocks_per_fit_);

    std::size_t const highest_factor = n_points_ * n_parameters_;

    std::size_t const highest_size_t_value = std::numeric_limits< std::size_t >::max();

    if (tmp_chunk_size > highest_size_t_value / highest_factor)
    {
        tmp_chunk_size = highest_size_t_value / highest_factor;
    }

    max_chunk_size_ = tmp_chunk_size;

    int i = 1;
    int const divisor = 10;
    while (tmp_chunk_size > divisor)
    {
        i *= divisor;
        tmp_chunk_size /= divisor;
    }
    max_chunk_size_ = max_chunk_size_ / i * i;
    max_chunk_size_ = std::min(max_chunk_size_, n_fits_);
}

void Info::configure()
{
    power_of_two_n_points_ = 1;
    while (power_of_two_n_points_ < n_points_)
    {
        power_of_two_n_points_ *= 2;
    }

    get_gpu_properties();
    set_blocks_per_fit();
    set_max_chunk_size();
}
<commit_msg>number of fits per block calculation updated<commit_after>#include "info.h"
#include <algorithm>

Info::Info() :
    n_parameters_(0),
    n_parameters_to_fit_(0),
    max_chunk_size_(0),
    max_n_iterations_(0),
    n_points_(0),
    power_of_two_n_points_(0),
    n_fits_(0),
    user_info_size_(0),
    n_fits_per_block_(0),
    n_blocks_per_fit_(0),
    model_id_(0),
    estimator_id_(0),
    max_threads_(0),
    max_blocks_(0),
    available_gpu_memory_(0)
{
}

Info::~Info(void)
{
}

void Info::set_number_of_parameters_to_fit(int const * const parameters_to_fit)
{
    n_parameters_to_fit_ = n_parameters_;

    for (int i = 0; i < n_parameters_; i++)
    {
        if (!parameters_to_fit[i])
        {
            n_parameters_to_fit_--;
        }
    }
}

void Info::set_fits_per_block(std::size_t const current_chunk_size)
{

    n_fits_per_block_ = std::max((max_threads_ / power_of_two_n_points_), 1);

    bool is_divisible = current_chunk_size % n_fits_per_block_ == 0;

    while (!is_divisible && (n_fits_per_block_ > 1))
    {
        n_fits_per_block_ -= 1;
        is_divisible = current_chunk_size % n_fits_per_block_ == 0;
    }

}

void Info::set_blocks_per_fit()
{
    n_blocks_per_fit_ = 1;

    if (power_of_two_n_points_ > max_threads_)
    {
        bool enough_threads = false;
        do
        {
            n_blocks_per_fit_ *= 2;
            enough_threads = power_of_two_n_points_ / n_blocks_per_fit_ < max_threads_;
        } while (!enough_threads);
    }
}

void Info::set_max_chunk_size()
{
    int one_fit_memory
        = sizeof(float)
        *(2 * n_points_                                     // data, values
        + 2 * n_parameters_                                 // parameters, prev_parameters
        + 1 * n_blocks_per_fit_                             // chi_square
        + 1 * n_parameters_to_fit_ * n_blocks_per_fit_      // gradient
        + 1 * n_parameters_to_fit_ * n_parameters_to_fit_   // hessian
        + 1 * n_parameters_to_fit_                          // delta
        + 1 * n_points_*n_parameters_                       // derivatives
        + 2)                                                // prev_chi_square, lambda
        + sizeof(int)
        * 4;                                                // state, finished, iteration_failed, n_iterations

    if (use_weights_)
        one_fit_memory += sizeof(float) * n_points_;

    std::size_t tmp_chunk_size = available_gpu_memory_ / one_fit_memory;

    if (tmp_chunk_size == 0)
    {
        throw std::runtime_error("not enough free GPU memory available");
    }

    tmp_chunk_size = (std::min)(tmp_chunk_size, max_blocks_ / n_blocks_per_fit_);

    std::size_t const highest_factor = n_points_ * n_parameters_;

    std::size_t const highest_size_t_value = std::numeric_limits< std::size_t >::max();

    if (tmp_chunk_size > highest_size_t_value / highest_factor)
    {
        tmp_chunk_size = highest_size_t_value / highest_factor;
    }

    max_chunk_size_ = tmp_chunk_size;

    int i = 1;
    int const divisor = 10;
    while (tmp_chunk_size > divisor)
    {
        i *= divisor;
        tmp_chunk_size /= divisor;
    }
    max_chunk_size_ = (max_chunk_size_ / i) * i;
    max_chunk_size_ = std::min(max_chunk_size_, n_fits_);
}

void Info::configure()
{
    power_of_two_n_points_ = 1;
    while (power_of_two_n_points_ < n_points_)
    {
        power_of_two_n_points_ *= 2;
    }

    get_gpu_properties();
    set_blocks_per_fit();
    set_max_chunk_size();
}
<|endoftext|>


<commit_before>/*
 * Runs StereoBM (block matching stereo) on images coming from LCM.
 * Written so that we can do comparisons between StereoBM and our 3D
 * system.
 *
 * Author: Andrew Barry, <abarry@csail.mit.edu> 2014
 *
 */

#include "bm-stereo.hpp"

using namespace std;

lcm_t * lcm;

// globals for subscription functions, so we can unsubscribe in the control-c handler
bot_core_image_t_subscription_t *stereo_image_left_sub;
bot_core_image_t_subscription_t *stereo_image_right_sub;
lcmt_stereo_subscription_t *stereo_replay_sub;

mutex left_mutex, right_mutex;

Mat left_image = Mat::zeros(240, 376, CV_8UC1);
Mat right_image = Mat::zeros(240, 376, CV_8UC1);

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

    string config_file = "";

    ConciseArgs parser(argc, argv);
    parser.add(config_file, "c", "config", "Configuration file containing camera GUIDs, etc.", true);
    parser.parse();

    OpenCvStereoConfig stereo_config;

    // parse the config file
    if (ParseConfigFile(config_file, &stereo_config) != true)
    {
        fprintf(stderr, "Failed to parse configuration file, quitting.\n");
        return 1;
    }

    // load calibration
    OpenCvStereoCalibration stereo_calibration;

    if (LoadCalibration(stereo_config.calibrationDir, &stereo_calibration) != true)
    {
        cerr << "Error: failed to read calibration files. Quitting." << endl;
        return 1;
    }

    lcm = lcm_create ("udpm://239.255.76.67:7667?ttl=0");
    if (!lcm)
    {
        fprintf(stderr, "lcm_create for recieve failed.  Quitting.\n");
        return 1;
    }

    BotParam *param = bot_param_new_from_server(lcm, 0);
    if (param == NULL) {
        fprintf(stderr, "Error: no param server!\n");
        return 1;
    }

    // if a channel exists, subscribe to it

    char *stereo_replay_channel;
    if (bot_param_get_str(param, "lcm_channels.stereo_replay", &stereo_replay_channel) >= 0) {
        stereo_replay_sub = lcmt_stereo_subscribe(lcm, stereo_replay_channel, &stereo_replay_handler, NULL);
    }

    char *stereo_image_left_channel;
    if (bot_param_get_str(param, "lcm_channels.stereo_image_left", &stereo_image_left_channel) >= 0) {
        stereo_image_left_sub = bot_core_image_t_subscribe(lcm, stereo_image_left_channel, &stereo_image_left_handler, NULL);
    }

    char *stereo_image_right_channel;
    if (bot_param_get_str(param, "lcm_channels.stereo_image_right", &stereo_image_right_channel) >= 0) {
        stereo_image_right_sub = bot_core_image_t_subscribe(lcm, stereo_image_right_channel, &stereo_image_right_handler, NULL);
    }

    // control-c handler
    signal(SIGINT,sighandler);

    namedWindow("Left", CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO);
    moveWindow("Left", 2700, 1000);

    namedWindow("Right", CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO);
    moveWindow("Right", 2700+400, 1000);

    namedWindow("Disparity", CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO);
    moveWindow("Disparity", 2700, 1000+350);

    StereoBM *stereo_bm = new StereoBM(CV_STEREO_BM_BASIC);

    cout << "Running..." << endl;

    while (true) {

        left_mutex.lock();
        right_mutex.lock();

        // remap images
        Mat remap_left(left_image.rows, left_image.cols, left_image.depth());
        Mat remap_right(right_image.rows, right_image.cols, right_image.depth());

        remap(left_image, remap_left, stereo_calibration.mx1fp, Mat(), INTER_NEAREST);
        remap(right_image, remap_right, stereo_calibration.mx2fp, Mat(), INTER_NEAREST);

        imshow("Left", remap_left);
        imshow("Right", remap_right);

        // do stereo processing
        Mat disparity_bm;
        (*stereo_bm)(remap_left, remap_right, disparity_bm); // opencv overloads the () operator (function call), but we have a pointer, so we must dereference first.

        Mat disp8;
        disparity_bm.convertTo(disp8, CV_8U, 255/(stereo_bm->state->numberOfDisparities*16.));

        // now strip out the values that are not at our disparity, so we can make a fair comparision
        // (and show the losses that come with our sparser technique)
        //Mat in_range;
        //inRange(disparity_bm, abs(state.disparity)-1, abs(state.disparity)+1, in_range);

        // display the disparity map
        //imshow("Debug 1", in_range);
        imshow("Disparity", disp8);

        right_mutex.unlock();
        left_mutex.unlock();

        char key = waitKey(1);

        if (key != 255 && key != -1)
        {
            cout << endl << key << endl;
        }

        switch (key)
        {
            case 'q':
                sighandler(0);
                break;
        }

        lcm_handle(lcm);
    }

    return 0;
}

void sighandler(int dum)
{
    printf("\n\nclosing... ");

    lcm_destroy (lcm);

    printf("done.\n");

    exit(0);
}

void stereo_image_left_handler(const lcm_recv_buf_t *rbuf, const char* channel, const bot_core_image_t *msg, void *user) {

    if (msg->pixelformat != 1196444237) { // PIXEL_FORMAT_MJPEG
        cerr << "Warning: reading images other than JPEG not yet implemented." << endl;
        return;
    }

    left_mutex.lock();

    left_image = Mat::zeros(msg->height, msg->width, CV_8UC1);

    // decompress JPEG
    jpeg_decompress_8u_gray(msg->data, msg->size, left_image.data, msg->width, msg->height, left_image.step);

    left_mutex.unlock();

}

void stereo_image_right_handler(const lcm_recv_buf_t *rbuf, const char* channel, const bot_core_image_t *msg, void *user) {

    if (msg->pixelformat != 1196444237) { // PIXEL_FORMAT_MJPEG
        cerr << "Warning: reading images other than JPEG not yet implemented." << endl;
        return;
    }

    right_mutex.lock();

    right_image = Mat::zeros(msg->height, msg->width, CV_8UC1);

    // decompress JPEG
    jpeg_decompress_8u_gray(msg->data, msg->size, right_image.data, msg->width, msg->height, right_image.step);

    right_mutex.unlock();

}

// for replaying videos, subscribe to the stereo replay channel and set the frame number
void stereo_replay_handler(const lcm_recv_buf_t *rbuf, const char* channel, const lcmt_stereo *msg, void *user) {
}

<commit_msg>incremental commit, working on stereobm<commit_after>/*
 * Runs StereoBM (block matching stereo) on images coming from LCM.
 * Written so that we can do comparisons between StereoBM and our 3D
 * system.
 *
 * Author: Andrew Barry, <abarry@csail.mit.edu> 2014
 *
 */

#include "bm-stereo.hpp"

using namespace std;

lcm_t * lcm;

// globals for subscription functions, so we can unsubscribe in the control-c handler
bot_core_image_t_subscription_t *stereo_image_left_sub;
bot_core_image_t_subscription_t *stereo_image_right_sub;
lcmt_stereo_subscription_t *stereo_replay_sub;

mutex left_mutex, right_mutex;

Mat left_image = Mat::zeros(240, 376, CV_8UC1);
Mat right_image = Mat::zeros(240, 376, CV_8UC1);

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

    string config_file = "";

    ConciseArgs parser(argc, argv);
    parser.add(config_file, "c", "config", "Configuration file containing camera GUIDs, etc.", true);
    parser.parse();

    OpenCvStereoConfig stereo_config;

    // parse the config file
    if (ParseConfigFile(config_file, &stereo_config) != true)
    {
        fprintf(stderr, "Failed to parse configuration file, quitting.\n");
        return 1;
    }

    // load calibration
    OpenCvStereoCalibration stereo_calibration;

    if (LoadCalibration(stereo_config.calibrationDir, &stereo_calibration) != true)
    {
        cerr << "Error: failed to read calibration files. Quitting." << endl;
        return 1;
    }

    lcm = lcm_create ("udpm://239.255.76.67:7667?ttl=0");
    if (!lcm)
    {
        fprintf(stderr, "lcm_create for recieve failed.  Quitting.\n");
        return 1;
    }

    BotParam *param = bot_param_new_from_server(lcm, 0);
    if (param == NULL) {
        fprintf(stderr, "Error: no param server!\n");
        return 1;
    }

    // if a channel exists, subscribe to it

    char *stereo_replay_channel;
    if (bot_param_get_str(param, "lcm_channels.stereo_replay", &stereo_replay_channel) >= 0) {
        stereo_replay_sub = lcmt_stereo_subscribe(lcm, stereo_replay_channel, &stereo_replay_handler, NULL);
    }

    char *stereo_image_left_channel;
    if (bot_param_get_str(param, "lcm_channels.stereo_image_left", &stereo_image_left_channel) >= 0) {
        stereo_image_left_sub = bot_core_image_t_subscribe(lcm, stereo_image_left_channel, &stereo_image_left_handler, NULL);
    }

    char *stereo_image_right_channel;
    if (bot_param_get_str(param, "lcm_channels.stereo_image_right", &stereo_image_right_channel) >= 0) {
        stereo_image_right_sub = bot_core_image_t_subscribe(lcm, stereo_image_right_channel, &stereo_image_right_handler, NULL);
    }

    // control-c handler
    signal(SIGINT,sighandler);

    namedWindow("Left", CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO);
    moveWindow("Left", 2700, 1000);

    namedWindow("Right", CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO);
    moveWindow("Right", 2700+400, 1000);

    namedWindow("Disparity", CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO);
    moveWindow("Disparity", 2700, 1000+350);

    StereoBM *stereo_bm = new StereoBM(CV_STEREO_BM_BASIC);

    cout << "Running..." << endl;

    while (true) {

        left_mutex.lock();
        right_mutex.lock();

        // remap images
        Mat remap_left(left_image.rows, left_image.cols, left_image.depth());
        Mat remap_right(right_image.rows, right_image.cols, right_image.depth());

        remap(left_image, remap_left, stereo_calibration.mx1fp, Mat(), INTER_NEAREST);
        remap(right_image, remap_right, stereo_calibration.mx2fp, Mat(), INTER_NEAREST);

        imshow("Left", remap_left);
        imshow("Right", remap_right);

        // do stereo processing
        Mat disparity_bm;
        (*stereo_bm)(remap_left, remap_right, disparity_bm); // opencv overloads the () operator (function call), but we have a pointer, so we must dereference first.

        Mat disp8;
        disparity_bm.convertTo(disp8, CV_8U, 255/(stereo_bm->state->numberOfDisparities*16.));

        // project into 3d space
        Mat image_3d;
        reprojectImageTo3D(disparity_bm, image_3d, stereo_calibration.qMat);

        // put these 3D coordinates in an LCM message
        lcmt_stereo msg;
        msg.timestamp = getTimestampNow();

        msg.frame_number = -1; // TODO

        int x[image_3d.cols * image_3d.rows];
        int y[image_3d.cols * image_3d.rows];
        int z[image_3d.cols * image_3d.rows];

        for (int i = 0; i < image_3d.cols * image_3d.rows; i++) {
            //x[i] = image_3d.at<
        }

        // now strip out the values that are not at our disparity, so we can make a fair comparision
        // (and show the losses that come with our sparser technique)
        //Mat in_range;
        //inRange(disparity_bm, abs(state.disparity)-1, abs(state.disparity)+1, in_range);

        // display the disparity map
        //imshow("Debug 1", in_range);
        imshow("Disparity", disp8);
        imshow("Disparity3d", image_3d);

        right_mutex.unlock();
        left_mutex.unlock();

        char key = waitKey(1);

        if (key != 255 && key != -1)
        {
            cout << endl << key << endl;
        }

        switch (key)
        {
            case 'q':
                sighandler(0);
                break;
        }

        lcm_handle(lcm);
    }

    return 0;
}

void sighandler(int dum)
{
    printf("\n\nclosing... ");

    lcm_destroy (lcm);

    printf("done.\n");

    exit(0);
}

void stereo_image_left_handler(const lcm_recv_buf_t *rbuf, const char* channel, const bot_core_image_t *msg, void *user) {

    if (msg->pixelformat != 1196444237) { // PIXEL_FORMAT_MJPEG
        cerr << "Warning: reading images other than JPEG not yet implemented." << endl;
        return;
    }

    left_mutex.lock();

    left_image = Mat::zeros(msg->height, msg->width, CV_8UC1);

    // decompress JPEG
    jpeg_decompress_8u_gray(msg->data, msg->size, left_image.data, msg->width, msg->height, left_image.step);

    left_mutex.unlock();

}

void stereo_image_right_handler(const lcm_recv_buf_t *rbuf, const char* channel, const bot_core_image_t *msg, void *user) {

    if (msg->pixelformat != 1196444237) { // PIXEL_FORMAT_MJPEG
        cerr << "Warning: reading images other than JPEG not yet implemented." << endl;
        return;
    }

    right_mutex.lock();

    right_image = Mat::zeros(msg->height, msg->width, CV_8UC1);

    // decompress JPEG
    jpeg_decompress_8u_gray(msg->data, msg->size, right_image.data, msg->width, msg->height, right_image.step);

    right_mutex.unlock();

}

// for replaying videos, subscribe to the stereo replay channel and set the frame number
void stereo_replay_handler(const lcm_recv_buf_t *rbuf, const char* channel, const lcmt_stereo *msg, void *user) {
}

<|endoftext|>


<commit_before>#include <cppunit/extensions/HelperMacros.h>

#include "server/SessionManager.h"
#include "provider/MockRandomProvider.h"
#include "util/Base64.h"
#include "provider/PocoRandomProvider.h"

using namespace std;

namespace BeeeOn {

class SessionManagerTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(SessionManagerTest);
	CPPUNIT_TEST(testOpenClose);
	CPPUNIT_TEST(testMaxUserSessions);
	CPPUNIT_TEST(testSessionTimeout);
	CPPUNIT_TEST_SUITE_END();
public:
	void setUp();
	void tearDown();
	void testOpenClose();
	void testMaxUserSessions();
	void testSessionTimeout();

private:
	SessionManager m_manager;
};

CPPUNIT_TEST_SUITE_REGISTRATION(SessionManagerTest);

void SessionManagerTest::setUp()
{
	// Set how many sessions is user allowed to have
	m_manager.setMaxUserSessions(10);

	// Set session expire time in seconds
	m_manager.setSessionExpireTime(1);
}

void SessionManagerTest::tearDown()
{
}

#define SESSION_ID64 string(\
	"0123456789abcdef"  \
	"0123456789abcdef"  \
	"0123456789abcdef"  \
	"0123456789abcdef")

void SessionManagerTest::testOpenClose()
{
	MockRandomProvider mockRandomProvider;
	mockRandomProvider.setNextRandom(SESSION_ID64);
	InsecureRandomProvider randomProvider;
	randomProvider.setProviderImpl(&mockRandomProvider);

	m_manager.setSecureRandomProvider(&randomProvider);

	UserID userID = UserID::parse("824b4831-6ce4-4614-8e02-8380d6d92f95");
	User user(userID);

	SessionID id = m_manager.open(user);
	CPPUNIT_ASSERT(Base64::decode(id).compare(SESSION_ID64) == 0);

	ExpirableSession::Ptr infoLookup;
	CPPUNIT_ASSERT(m_manager.lookup(id, infoLookup));

	m_manager.close(id);
	CPPUNIT_ASSERT(!m_manager.lookup(id, infoLookup));
}

// Open 11 new sessions where 11th open should throw an exception
void SessionManagerTest::testMaxUserSessions()
{
	PocoRandomProvider pocoProvider;
	UserID userID = UserID::parse("824b4831-6ce4-4614-8e02-8380d6d92f95");

	m_manager.setSecureRandomProvider(&pocoProvider);

	for (int i = 10; i >= 0; --i)
		CPPUNIT_ASSERT_NO_THROW(m_manager.open(userID));

	CPPUNIT_ASSERT_THROW(m_manager.open(userID), Poco::IllegalStateException);
}

void SessionManagerTest::testSessionTimeout()
{
	// Sleep for 1 second + a little bit of overhead.
	// Tests whether the session really expired.
	ExpirableSession::Ptr infoLookup;
	PocoRandomProvider pocoProvider;

	m_manager.setSecureRandomProvider(&pocoProvider);

	UserID userID = UserID::parse("824b4831-6ce4-4614-8e02-8380d6d92f95");
	SessionID id = m_manager.open(userID);

	usleep(1100000);
	CPPUNIT_ASSERT(!m_manager.lookup(id, infoLookup));
}
}
<commit_msg>SessionManagerTest: fix +/-1 bug in testMaxUserSessions<commit_after>#include <cppunit/extensions/HelperMacros.h>

#include "server/SessionManager.h"
#include "provider/MockRandomProvider.h"
#include "util/Base64.h"
#include "provider/PocoRandomProvider.h"

using namespace std;

namespace BeeeOn {

class SessionManagerTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(SessionManagerTest);
	CPPUNIT_TEST(testOpenClose);
	CPPUNIT_TEST(testMaxUserSessions);
	CPPUNIT_TEST(testSessionTimeout);
	CPPUNIT_TEST_SUITE_END();
public:
	void setUp();
	void tearDown();
	void testOpenClose();
	void testMaxUserSessions();
	void testSessionTimeout();

private:
	SessionManager m_manager;
};

CPPUNIT_TEST_SUITE_REGISTRATION(SessionManagerTest);

void SessionManagerTest::setUp()
{
	// Set how many sessions is user allowed to have
	m_manager.setMaxUserSessions(10);

	// Set session expire time in seconds
	m_manager.setSessionExpireTime(1);
}

void SessionManagerTest::tearDown()
{
}

#define SESSION_ID64 string(\
	"0123456789abcdef"  \
	"0123456789abcdef"  \
	"0123456789abcdef"  \
	"0123456789abcdef")

void SessionManagerTest::testOpenClose()
{
	MockRandomProvider mockRandomProvider;
	mockRandomProvider.setNextRandom(SESSION_ID64);
	InsecureRandomProvider randomProvider;
	randomProvider.setProviderImpl(&mockRandomProvider);

	m_manager.setSecureRandomProvider(&randomProvider);

	UserID userID = UserID::parse("824b4831-6ce4-4614-8e02-8380d6d92f95");
	User user(userID);

	SessionID id = m_manager.open(user);
	CPPUNIT_ASSERT(Base64::decode(id).compare(SESSION_ID64) == 0);

	ExpirableSession::Ptr infoLookup;
	CPPUNIT_ASSERT(m_manager.lookup(id, infoLookup));

	m_manager.close(id);
	CPPUNIT_ASSERT(!m_manager.lookup(id, infoLookup));
}

// Open 11 new sessions where 11th open should throw an exception
void SessionManagerTest::testMaxUserSessions()
{
	PocoRandomProvider pocoProvider;
	UserID userID = UserID::parse("824b4831-6ce4-4614-8e02-8380d6d92f95");

	m_manager.setSecureRandomProvider(&pocoProvider);

	for (int i = 0; i < 10; ++i)
		CPPUNIT_ASSERT_NO_THROW(m_manager.open(userID));

	CPPUNIT_ASSERT_THROW(m_manager.open(userID), Poco::IllegalStateException);
}

void SessionManagerTest::testSessionTimeout()
{
	// Sleep for 1 second + a little bit of overhead.
	// Tests whether the session really expired.
	ExpirableSession::Ptr infoLookup;
	PocoRandomProvider pocoProvider;

	m_manager.setSecureRandomProvider(&pocoProvider);

	UserID userID = UserID::parse("824b4831-6ce4-4614-8e02-8380d6d92f95");
	SessionID id = m_manager.open(userID);

	usleep(1100000);
	CPPUNIT_ASSERT(!m_manager.lookup(id, infoLookup));
}
}
<|endoftext|>


<commit_before>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

#include "dmx/EnttecDevice.h"
#include "dmx/Utilities.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class DMXBasicApp : public App {
public:
	void setup() override;
	void mouseDown(MouseEvent event) override;
	void keyDown(KeyEvent event) override;
	void update() override;
	void draw() override;
private:
	dmx::EnttecDeviceRef				_device;
	dmx::ColorBuffer						_buffer;
	dmx::EnttecDevice::Settings _settings;
};

void DMXBasicApp::setup()
{
	// Connect to enttec device and run data loop at 30 fps.
	_device = std::make_shared<dmx::EnttecDevice>("tty.usbserial-ENWER12L", 30);
	// Load the device settings synchronously.
	_settings = _device->loadSettings().get();
	console() << _settings << endl;
}

void DMXBasicApp::mouseDown( MouseEvent event )
{
	auto channel = mix<size_t>(0, _buffer.size(), (float)event.getPos().x / getWindowWidth());
	auto value = mix(0, 255, (float)event.getPos().y / getWindowHeight());
	_buffer.setChannelValues(channel, Color8u(value, value, value));
}

void DMXBasicApp::keyDown(cinder::app::KeyEvent event)
{

}

void DMXBasicApp::update()
{
	_device->bufferData(_buffer);
}

void DMXBasicApp::draw()
{
	gl::clear( Color( 0, 0, 0 ) );
}

CINDER_APP( DMXBasicApp, RendererGl )
<commit_msg>List devices in sample and interact with drag.<commit_after>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

#include "dmx/EnttecDevice.h"
#include "dmx/Utilities.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class DMXBasicApp : public App {
public:
	void setup() override;
	void mouseDrag(MouseEvent event) override;
	void keyDown(KeyEvent event) override;
	void update() override;
	void draw() override;
private:
	dmx::EnttecDeviceRef				_device;
	dmx::ColorBuffer						_buffer;
	dmx::EnttecDevice::Settings _settings;
};

void DMXBasicApp::setup()
{
    auto devices = Serial::getDevices();
    for (auto &device: devices) {
        console() << device.getName() << " at " << device.getPath() << endl;
    }
	// Connect to enttec device and run data loop at 30 fps.
	_device = std::make_shared<dmx::EnttecDevice>("tty.usbserial-EN", 30);
	// Load the device settings synchronously.
	_settings = _device->loadSettings().get();
	console() << _settings << endl;
    _settings.device_fps = 30;
    _device->applySettings(_settings);
//    _settings = _device->loadSettings().get();
//    console() << "after change: " << _settings << endl;
}

void DMXBasicApp::mouseDrag( MouseEvent event )
{
    auto channel = mix<size_t>(0, _buffer.size(), (float)event.getPos().x / getWindowWidth());
    auto value = mix(0, 255, (float)event.getPos().y / getWindowHeight());
    _buffer.setChannelValue(channel, value);
}

void DMXBasicApp::keyDown(cinder::app::KeyEvent event)
{

}

void DMXBasicApp::update()
{
	_device->bufferData(_buffer);
}

void DMXBasicApp::draw()
{
	gl::clear( Color( 0, 0, 0 ) );
}

CINDER_APP( DMXBasicApp, RendererGl )
<|endoftext|>


<commit_before>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "base/object_watcher.h"

#include "base/logging.h"

namespace base {

//-----------------------------------------------------------------------------

struct ObjectWatcher::Watch : public Task {
  ObjectWatcher* watcher;    // The associated ObjectWatcher instance
  HANDLE object;             // The object being watched
  HANDLE wait_object;        // Returned by RegisterWaitForSingleObject
  MessageLoop* origin_loop;  // Used to get back to the origin thread
  Delegate* delegate;        // Delegate to notify when signaled
  bool did_signal;           // DoneWaiting was called

  virtual void Run() {
    // The watcher may have already been torn down, in which case we need to
    // just get out of dodge.
    if (!watcher)
      return;

    DCHECK(did_signal);
    watcher->StopWatching();

    delegate->OnObjectSignaled(object);
  }
};

//-----------------------------------------------------------------------------

ObjectWatcher::ObjectWatcher() : watch_(NULL) {
}

ObjectWatcher::~ObjectWatcher() {
  StopWatching();
}

bool ObjectWatcher::StartWatching(HANDLE object, Delegate* delegate) {
  if (watch_) {
    NOTREACHED() << "Already watching an object";
    return false;
  }

  Watch* watch = new Watch;
  watch->watcher = this;
  watch->object = object;
  watch->origin_loop = MessageLoop::current();
  watch->delegate = delegate;
  watch->did_signal = false;

  // Since our job is to just notice when an object is signaled and report the
  // result back to this thread, we can just run on a Windows wait thread.
  DWORD wait_flags = WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE;

  if (!RegisterWaitForSingleObject(&watch->wait_object, object, DoneWaiting,
                                   watch, INFINITE, wait_flags)) {
    NOTREACHED() << "RegisterWaitForSingleObject failed: " << GetLastError();
    delete watch;
    return false;
  }

  watch_ = watch;

  // We need to know if the current message loop is going away so we can
  // prevent the wait thread from trying to access a dead message loop.
  MessageLoop::current()->AddDestructionObserver(this);
  return true;
}

bool ObjectWatcher::StopWatching() {
  if (!watch_)
    return false;

  // Make sure ObjectWatcher is used in a single-threaded fashion.
  DCHECK(watch_->origin_loop == MessageLoop::current());

  // If DoneWaiting is in progress, we wait for it to finish.  We know whether
  // DoneWaiting happened or not by inspecting the did_signal flag.
  if (!UnregisterWaitEx(watch_->wait_object, INVALID_HANDLE_VALUE)) {
    NOTREACHED() << "UnregisterWaitEx failed: " << GetLastError();
    return false;
  }

  // Make sure that we see any mutation to did_signal.  This should be a no-op
  // since we expect that UnregisterWaitEx resulted in a memory barrier, but
  // just to be sure, we're going to be explicit.
  MemoryBarrier();

  // If the watch has been posted, then we need to make sure it knows not to do
  // anything once it is run.
  watch_->watcher = NULL;

  // If DoneWaiting was called, then the watch would have been posted as a
  // task, and will therefore be deleted by the MessageLoop.  Otherwise, we
  // need to take care to delete it here.
  if (!watch_->did_signal)
    delete watch_;

  watch_ = NULL;

  MessageLoop::current()->RemoveDestructionObserver(this);
  return true;
}

// static
void CALLBACK ObjectWatcher::DoneWaiting(void* param, BOOLEAN timed_out) {
  DCHECK(!timed_out);

  Watch* watch = static_cast<Watch*>(param);

  // Record that we ran this function.
  watch->did_signal = true;

  // TODO(darin): This is just a test.
  watch->set_priority(1000);

  // We rely on the locking in PostTask() to ensure that a memory barrier is
  // provided, which in turn ensures our change to did_signal can be observed
  // on the target thread.
  watch->origin_loop->PostTask(FROM_HERE, watch);
}

void ObjectWatcher::WillDestroyCurrentMessageLoop() {
  // Need to shutdown the watch so that we don't try to access the MessageLoop
  // after this point.
  StopWatching();
}

}  // namespace base
<commit_msg>experiment with APCs<commit_after>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "base/object_watcher.h"

#include "base/histogram.h"
#include "base/logging.h"

namespace base {

static int live_watches = 0;

//-----------------------------------------------------------------------------

struct ObjectWatcher::Watch {
  ObjectWatcher* watcher;    // The associated ObjectWatcher instance
  HANDLE object;             // The object being watched
  HANDLE wait_object;        // Returned by RegisterWaitForSingleObject
  HANDLE origin_thread;
  Delegate* delegate;        // Delegate to notify when signaled
  bool did_signal;           // DoneWaiting was called

  TimeTicks signal_time;

  void Run() {
    // The watcher may have already been torn down, in which case we need to
    // just get out of dodge.
    if (!watcher)
      return;

    DCHECK(did_signal);
    watcher->StopWatching();

    TimeDelta delta = TimeTicks::Now() - signal_time;
    HISTOGRAM_TIMES(L"ObjectWatcher_CallbackLatency", delta);

    delegate->OnObjectSignaled(object);
  }

  ~Watch() {
    CloseHandle(origin_thread);
  }

  static void CALLBACK ReturnToOriginThread(ULONG_PTR param) {
    Watch* self = reinterpret_cast<Watch*>(param);
    self->Run();
    delete self;
  }
};

//-----------------------------------------------------------------------------

ObjectWatcher::ObjectWatcher() : watch_(NULL) {
}

ObjectWatcher::~ObjectWatcher() {
  StopWatching();
}

bool ObjectWatcher::StartWatching(HANDLE object, Delegate* delegate) {
  if (watch_) {
    NOTREACHED() << "Already watching an object";
    return false;
  }

  Watch* watch = new Watch;
  watch->watcher = this;
  watch->object = object;
  watch->delegate = delegate;
  watch->did_signal = false;

  watch->origin_thread =
      OpenThread(THREAD_SET_CONTEXT, FALSE, GetCurrentThreadId());

  // Since our job is to just notice when an object is signaled and report the
  // result back to this thread, we can just run on a Windows wait thread.
  DWORD wait_flags = WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE;

  if (!RegisterWaitForSingleObject(&watch->wait_object, object, DoneWaiting,
                                   watch, INFINITE, wait_flags)) {
    NOTREACHED() << "RegisterWaitForSingleObject failed: " << GetLastError();
    delete watch;
    return false;
  }

  watch_ = watch;

  ++live_watches;
  HISTOGRAM_COUNTS(L"ObjectWatcher_LiveWatches", live_watches);

  // We need to know if the current message loop is going away so we can
  // prevent the wait thread from trying to access a dead message loop.
  MessageLoop::current()->AddDestructionObserver(this);
  return true;
}

bool ObjectWatcher::StopWatching() {
  if (!watch_)
    return false;

  --live_watches;

  // Make sure ObjectWatcher is used in a single-threaded fashion.
  DCHECK(GetThreadId(watch_->origin_thread) == GetCurrentThreadId());

  // If DoneWaiting is in progress, we wait for it to finish.  We know whether
  // DoneWaiting happened or not by inspecting the did_signal flag.
  if (!UnregisterWaitEx(watch_->wait_object, INVALID_HANDLE_VALUE)) {
    NOTREACHED() << "UnregisterWaitEx failed: " << GetLastError();
    return false;
  }

  // Make sure that we see any mutation to did_signal.  This should be a no-op
  // since we expect that UnregisterWaitEx resulted in a memory barrier, but
  // just to be sure, we're going to be explicit.
  MemoryBarrier();

  // If the watch has been posted, then we need to make sure it knows not to do
  // anything once it is run.
  watch_->watcher = NULL;

  // If DoneWaiting was called, then the watch would have been posted as a
  // task, and will therefore be deleted by the MessageLoop.  Otherwise, we
  // need to take care to delete it here.
  if (!watch_->did_signal)
    delete watch_;

  watch_ = NULL;

  MessageLoop::current()->RemoveDestructionObserver(this);
  return true;
}

// static
void CALLBACK ObjectWatcher::DoneWaiting(void* param, BOOLEAN timed_out) {
  DCHECK(!timed_out);

  Watch* watch = static_cast<Watch*>(param);

  // Record that we ran this function.
  watch->did_signal = true;

  watch->signal_time = TimeTicks::Now();

  QueueUserAPC(Watch::ReturnToOriginThread, watch->origin_thread,
      reinterpret_cast<ULONG_PTR>(watch));
}

void ObjectWatcher::WillDestroyCurrentMessageLoop() {
  // Need to shutdown the watch so that we don't try to access the MessageLoop
  // after this point.
  StopWatching();
}

}  // namespace base
<|endoftext|>


<commit_before>/*
	Solar calculations
	solarcal.cpp - Library to calculated solar data
	Created by Orlando Aguirre, July 27, 2015
	Release into the public domain.
*/

#include "Arduino.h"
#include <solarcalc.h>
#include <math.h>
#define pi 3.14159265358979323846
#define Radians 0.017453292519943295769 // (pi/180)
#define Degrees 57.295779513082320877  // (180/pi)

solarcalc::solarcalc(float _latitude, float _longitude, float _zenith, float _timezone) {

  latitude   = _latitude;
  longitude  = _longitude;
  zenith     = _zenith;
  timezone   = _timezone;
}

void solarcalc::time(int _year, int _month, int _day, int _hour, int _minute, int _second) {

  year = _year;
  month = _month;
  day = _day;
  hour = _hour;
  minute = _minute;
  second = _second;

}

void solarcalc::calculations() {

  current_hour = float(hour) + (float(minute) / 60) + (float(second) / 3600);
  a = floor((14 - month) / 12);
  y = year + 4800 - a;
  m = month - 12 * a - 3;
  //Julian Date
  JD = (day + floor((153 * m + 2) / 5) + 365 * y + floor(y / 4) - floor(y / 100) + floor(y / 400) - 32045) + (current_hour - 12) / 24;
  //Julian Century
  JC = (JD - 2451545) / 36525;
  //Geom Mean Long Sun (deg)
  GMLS = fmod(280.46646 + JC * (36000.76983 + JC * 0.0003032),360);
  //Geom Mean Anom Sun (deg)
  GMAS = 357.52911 + JC * (35999.05029 - 0.0001537 * JC);
  //Eccent Earth Orbit
  EEO = 0.016708634 - JC * (0.000042037 + 0.0000001267 * JC);
  //Sun Eq of Ctr
  EMoC = sin(Radians * (GMAS)) * (1.914602 - JC * (0.004817 + 0.000014 * JC)) + sin(Radians * (2 * GMAS)) * (0.019993 - 0.000101 * JC) + sin(Radians * (3 * GMAS)) * 0.000289;
  //Sun True Long (deg)
  STL = GMLS + EMoC;
  //Sun True Anom (deg)
  STA = GMAS + EMoC;
  //Sun Rad Vector (AUs)
  SRV = (1.000001018 * (1 - EEO * EEO)) / (1 + EEO * cos(Radians * (STA)));
  //Sun App Long (deg)
  SAL = STL - 0.00569 - 0.00478 * sin(Radians * (125.04 - 1934.136 * JC));
  //Mean Obliq Ecliptic (deg)
  MOE = 23 + (26 + ((21.448 - JC * (46.815 + JC * (0.00059 - JC * 0.001813)))) / 60) / 60;
  //Obliq Corr (deg)
  OC = MOE + 0.00256 * cos(Radians * (125.04 - 1934.136 * JC));
  //Sun Rt Ascen (deg)
  SRA = Degrees * (atan2(cos(Radians * (SAL)), cos(Radians * (OC)) * sin(Radians * (SAL))));
  //Sun Declin (deg)
  SDec = Degrees * (asin(sin(Radians * (OC)) * sin(Radians * (SAL))));
  //var y
  var_y = tan(Radians * (OC / 2)) * tan(Radians * (OC / 2));
  //Eq of Time (minutes)
  EoT = 4 * Degrees * (var_y * sin(2 * Radians * (GMLS)) - 2 * EEO * sin(Radians * (GMAS)) + 4 * EEO * var_y * sin(Radians * (GMAS)) * cos(2 * Radians * (GMLS)) - 0.5 * var_y * var_y * sin(4 * Radians * (GMLS)) - 1.25 * EEO * EEO * sin(2 * Radians * (GMAS)));
  //HA Sunrise (deg)
  HA = Degrees * (acos(cos(Radians * (90.833)) / (cos(Radians * (latitude)) * cos(Radians * (SDec))) - tan(Radians * (latitude)) * tan(Radians * (SDec))));
  //Solar Noon (LST)
  Snoon = (720 - 4 * longitude - EoT + timezone * 60) / 1440 * 24;
  //Sunrise Time (LST)
  Sunrise = Snoon - HA * 4 / 1440 * 24;
  //Sunset Time (LST)
  Sunset = Snoon + HA * 4 / 1440 * 24;
  //Sunlight Duration (minutes)
  SDur = 8 * HA;
  //True Solar Time (min)
  TST = fmod(current_hour * 1440 + EoT + 4 * longitude - 60 * timezone,1440);
  //Hour Angle (deg)
  if (TST / 4 < 0) {
    HAng = TST / 4 + 180;
  }
  else {
    HAng = TST / 4 - 180;
  }
  //Solar Zenith Angle (deg)
  SZA = Degrees * (acos(sin(Radians * (latitude)) * sin(Radians * (SDec)) + cos(Radians * (latitude)) * cos(Radians * (SDec)) * cos(Radians * (HAng))));
  //Solar Elevation Angle (deg)
  SEA = 90 - SZA;
  //Approx Atmospheric Refraction (deg)
  if (SEA > 85) {
    AAR = 0;
  }
  else {
    if (SEA > 5) {
      AAR = (58.1 / tan(Radians * (SEA)) - 0.07 / pow(tan(Radians * (SEA)), 3) + 0.000086 / pow(tan(Radians * (SEA)), 5)) / 3600;
    }
    else {
      if (SEA > -0.575) {
        AAR = (1735 + SEA * (-518.2 + SEA * (103.4 + SEA * (-12.79 + SEA * 0.711)))) / 3600;
      }
      else {
        AAR = (-20.772 / tan(Radians * (SEA))) / 3600;
      }
    }
  }
  //Solar Elevation corrected for atm refraction (deg)
  SEAtmR = SEA + AAR;
  //Solar Azimuth Angle (deg cw from N)
  if (HAng > 0) {
    SAzA = fmod(Degrees * (acos(((sin(Radians * (latitude)) * cos(Radians * (SZA))) - sin(Radians * (SDec))) / (cos(Radians * (latitude)) * sin(Radians * (SZA))))) + 180,360);
  }
  else {
    SAzA = fmod(540 - Degrees * (acos(((sin(Radians * (latitude)) * cos(Radians * (SZA))) - sin(Radians * (SDec))) / (cos(Radians * (latitude)) * sin(Radians * (SZA))))),360);
  }

}

float solarcalc::current_time() {
  return current_hour;
}

float solarcalc::julian_date() {
  return JD;
}

float solarcalc::julian_century() {
  return JC;
}

float solarcalc::solar_noon() {
  return Snoon;
}

float solarcalc::sunrise_time() {
  return Sunrise;
}

float solarcalc::sunset_time() {
  return Sunset;
}

float solarcalc::solar_elevation_atm() {
  return SEAtmR;
}

float solarcalc::equation_of_time() {
  return EoT;
}

float solarcalc::solar_declination() {
  return SDec;
}

float solarcalc::solar_elevation_angle() {
  return SAzA;
}
<commit_msg>Update solarcalc.cpp<commit_after>/*
	Solar calculations
	solarcal.cpp - Library to calculated solar data
	Created by Orlando Aguirre, July 27, 2015
	Release into the public domain.
*/
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#elif defined(SPARK)
#include "application.h"
#endif

#include <solarcalc.h>
#include <math.h>
#define pi 3.14159265358979323846
#define Radians 0.017453292519943295769 // (pi/180)
#define Degrees 57.295779513082320877  // (180/pi)

solarcalc::solarcalc(float _latitude, float _longitude, float _zenith, float _timezone) {

  latitude   = _latitude;
  longitude  = _longitude;
  zenith     = _zenith;
  timezone   = _timezone;
}

void solarcalc::time(int _year, int _month, int _day, int _hour, int _minute, int _second) {

  year = _year;
  month = _month;
  day = _day;
  hour = _hour;
  minute = _minute;
  second = _second;

}

void solarcalc::calculations() {

  current_hour = float(hour) + (float(minute) / 60) + (float(second) / 3600);
  a = floor((14 - month) / 12);
  y = year + 4800 - a;
  m = month - 12 * a - 3;
  //Julian Date
  JD = (day + floor((153 * m + 2) / 5) + 365 * y + floor(y / 4) - floor(y / 100) + floor(y / 400) - 32045) + (current_hour - 12) / 24;
  //Julian Century
  JC = (JD - 2451545) / 36525;
  //Geom Mean Long Sun (deg)
  GMLS = fmod(280.46646 + JC * (36000.76983 + JC * 0.0003032),360);
  //Geom Mean Anom Sun (deg)
  GMAS = 357.52911 + JC * (35999.05029 - 0.0001537 * JC);
  //Eccent Earth Orbit
  EEO = 0.016708634 - JC * (0.000042037 + 0.0000001267 * JC);
  //Sun Eq of Ctr
  EMoC = sin(Radians * (GMAS)) * (1.914602 - JC * (0.004817 + 0.000014 * JC)) + sin(Radians * (2 * GMAS)) * (0.019993 - 0.000101 * JC) + sin(Radians * (3 * GMAS)) * 0.000289;
  //Sun True Long (deg)
  STL = GMLS + EMoC;
  //Sun True Anom (deg)
  STA = GMAS + EMoC;
  //Sun Rad Vector (AUs)
  SRV = (1.000001018 * (1 - EEO * EEO)) / (1 + EEO * cos(Radians * (STA)));
  //Sun App Long (deg)
  SAL = STL - 0.00569 - 0.00478 * sin(Radians * (125.04 - 1934.136 * JC));
  //Mean Obliq Ecliptic (deg)
  MOE = 23 + (26 + ((21.448 - JC * (46.815 + JC * (0.00059 - JC * 0.001813)))) / 60) / 60;
  //Obliq Corr (deg)
  OC = MOE + 0.00256 * cos(Radians * (125.04 - 1934.136 * JC));
  //Sun Rt Ascen (deg)
  SRA = Degrees * (atan2(cos(Radians * (SAL)), cos(Radians * (OC)) * sin(Radians * (SAL))));
  //Sun Declin (deg)
  SDec = Degrees * (asin(sin(Radians * (OC)) * sin(Radians * (SAL))));
  //var y
  var_y = tan(Radians * (OC / 2)) * tan(Radians * (OC / 2));
  //Eq of Time (minutes)
  EoT = 4 * Degrees * (var_y * sin(2 * Radians * (GMLS)) - 2 * EEO * sin(Radians * (GMAS)) + 4 * EEO * var_y * sin(Radians * (GMAS)) * cos(2 * Radians * (GMLS)) - 0.5 * var_y * var_y * sin(4 * Radians * (GMLS)) - 1.25 * EEO * EEO * sin(2 * Radians * (GMAS)));
  //HA Sunrise (deg)
  HA = Degrees * (acos(cos(Radians * (90.833)) / (cos(Radians * (latitude)) * cos(Radians * (SDec))) - tan(Radians * (latitude)) * tan(Radians * (SDec))));
  //Solar Noon (LST)
  Snoon = (720 - 4 * longitude - EoT + timezone * 60) / 1440 * 24;
  //Sunrise Time (LST)
  Sunrise = Snoon - HA * 4 / 1440 * 24;
  //Sunset Time (LST)
  Sunset = Snoon + HA * 4 / 1440 * 24;
  //Sunlight Duration (minutes)
  SDur = 8 * HA;
  //True Solar Time (min)
  TST = fmod(current_hour * 1440 + EoT + 4 * longitude - 60 * timezone,1440);
  //Hour Angle (deg)
  if (TST / 4 < 0) {
    HAng = TST / 4 + 180;
  }
  else {
    HAng = TST / 4 - 180;
  }
  //Solar Zenith Angle (deg)
  SZA = Degrees * (acos(sin(Radians * (latitude)) * sin(Radians * (SDec)) + cos(Radians * (latitude)) * cos(Radians * (SDec)) * cos(Radians * (HAng))));
  //Solar Elevation Angle (deg)
  SEA = 90 - SZA;
  //Approx Atmospheric Refraction (deg)
  if (SEA > 85) {
    AAR = 0;
  }
  else {
    if (SEA > 5) {
      AAR = (58.1 / tan(Radians * (SEA)) - 0.07 / pow(tan(Radians * (SEA)), 3) + 0.000086 / pow(tan(Radians * (SEA)), 5)) / 3600;
    }
    else {
      if (SEA > -0.575) {
        AAR = (1735 + SEA * (-518.2 + SEA * (103.4 + SEA * (-12.79 + SEA * 0.711)))) / 3600;
      }
      else {
        AAR = (-20.772 / tan(Radians * (SEA))) / 3600;
      }
    }
  }
  //Solar Elevation corrected for atm refraction (deg)
  SEAtmR = SEA + AAR;
  //Solar Azimuth Angle (deg cw from N)
  if (HAng > 0) {
    SAzA = fmod(Degrees * (acos(((sin(Radians * (latitude)) * cos(Radians * (SZA))) - sin(Radians * (SDec))) / (cos(Radians * (latitude)) * sin(Radians * (SZA))))) + 180,360);
  }
  else {
    SAzA = fmod(540 - Degrees * (acos(((sin(Radians * (latitude)) * cos(Radians * (SZA))) - sin(Radians * (SDec))) / (cos(Radians * (latitude)) * sin(Radians * (SZA))))),360);
  }

}

float solarcalc::current_time() {
  return current_hour;
}

float solarcalc::julian_date() {
  return JD;
}

float solarcalc::julian_century() {
  return JC;
}

float solarcalc::solar_noon() {
  return Snoon;
}

float solarcalc::sunrise_time() {
  return Sunrise;
}

float solarcalc::sunset_time() {
  return Sunset;
}

float solarcalc::solar_elevation_atm() {
  return SEAtmR;
}

float solarcalc::equation_of_time() {
  return EoT;
}

float solarcalc::solar_declination() {
  return SDec;
}

float solarcalc::solar_elevation_angle() {
  return SAzA;
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2014 Daniel Vrátil <dvratil@redhat.com>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "tagstore.h"
#include "scope.h"
#include "tagfetchhelper.h"
#include "imapstreamparser.h"
#include "response.h"
#include "storage/datastore.h"
#include "libs/protocol_p.h"
#include "connection.h"

using namespace Akonadi::Server;

TagStore::TagStore()
  : Handler()
{
}

TagStore::~TagStore()
{
}

bool TagStore::parseStream()
{
  const qint64 tagId = m_streamParser->readNumber();

  if ( !m_streamParser->hasList() ) {
    failureResponse( "No changes to store" );
    return false;
  }

  Tag changedTag = Tag::retrieveById( tagId );
  if ( !changedTag.isValid() ) {
    throw HandlerException( "No such tag" );
  }

  // Retrieve all tag's attributes
  const TagAttribute::List attributes = TagAttribute::retrieveFiltered( TagAttribute::tagIdFullColumnName(), tagId );
  QMap<QByteArray,TagAttribute> attributesMap;
  Q_FOREACH ( const TagAttribute &attribute, attributes ) {
    attributesMap.insert( attribute.type(), attribute );
  }

  bool tagRemoved = false;
  m_streamParser->beginList();
  while ( !m_streamParser->atListEnd() ) {
    const QByteArray attr = m_streamParser->readString();

    if ( attr == AKONADI_PARAM_PARENT ) {
      const qint64 parent = m_streamParser->readNumber();
            changedTag.setParentId( parent );
    } else if ( attr == AKONADI_PARAM_GID ) {
      throw HandlerException( "Changing tag GID is not allowed" );
    } else if ( attr == AKONADI_PARAM_UID ) {
      throw HandlerException( "Changing tag UID is not allowed" );
    } else if ( attr == AKONADI_PARAM_MIMETYPE ) {
        const QString &typeName = m_streamParser->readUtf8String();
        TagType type = TagType::retrieveByName(typeName);
        if (!type.isValid()) {
            TagType newType;
            newType.setName(typeName);
            if (!newType.insert()) {
                throw HandlerException( "Failed to insert type" );
            }
            type = newType;
        }
        changedTag.setTagType(type);
    } else if ( attr == AKONADI_PARAM_REMOTEID ) {
        const QString &remoteId = m_streamParser->readUtf8String();
        if (!connection()->context()->resource().isValid()) {
            throw HandlerException( "Only resources can change the remoteid" );
        }
        TagRemoteIdResourceRelation::remove(TagRemoteIdResourceRelation::resourceIdFullColumnName(), connection()->context()->resource().id());

        if (!remoteId.isEmpty()) {
            TagRemoteIdResourceRelation remoteIdRelation;
            remoteIdRelation.setRemoteId(remoteId);
            remoteIdRelation.setResourceId(connection()->context()->resource().id());
            remoteIdRelation.setTag(changedTag);
            if (!remoteIdRelation.insert()) {
                throw HandlerException( "Failed to insert remotedid resource relation" );
            }
        } else {
            const int tagRidsCount = TagRemoteIdResourceRelation::count(TagRemoteIdResourceRelation::tagIdColumn(), changedTag.id());
            // We just removed the last RID of the tag, which means that no other
            // resource owns this tag, so we have to remove it to simulate tag
            // removal
            if (tagRidsCount == 0) {
                if (!DataStore::self()->removeTags(Tag::List() << changedTag)) {
                    throw HandlerException( "Failed to remove tag" );
                }
                tagRemoved = true;
                break;
            }
        }
    } else {
      if ( attr.startsWith( '-' ) ) {
        const QByteArray attrName = attr.mid( 1 );
        if ( attributesMap.contains( attrName ) ) {
          TagAttribute attribute = attributesMap.value( attrName );
          TagAttribute::remove( attribute.id() );
        }
      } else if ( attributesMap.contains( attr ) ) {
        const QByteArray value = m_streamParser->readString();
        TagAttribute attribute = attributesMap.value( attr );
        attribute.setValue( value );
        if (!attribute.update()) {
            throw HandlerException("Failed to update attribute");
        }
      } else {
        const QByteArray value = m_streamParser->readString();
        TagAttribute attribute;
        attribute.setTagId( tagId );
        attribute.setType( attr );
        attribute.setValue( value );
        if (!attribute.insert()) {
            throw HandlerException("Failed to insert attribute");
        }
      }
    }
  }

  if (!tagRemoved) {
      if (!changedTag.update()) {
        throw HandlerException( "Failed to store changes" );
      }
      DataStore::self()->notificationCollector()->tagChanged( changedTag );

      ImapSet set;
      set.add( QVector<qint64>() << tagId );
      TagFetchHelper helper( connection(), set );
      connect( &helper, SIGNAL(responseAvailable(Akonadi::Server::Response)),
               this, SIGNAL(responseAvailable(Akonadi::Server::Response)) );
      if ( !helper.fetchTags( AKONADI_CMD_TAGFETCH ) ) {
        return false;
      }
  } else {
      QByteArray str = QByteArray::number( tagId ) + " TAGREMOVE";
      Response response;
      response.setUntagged();
      response.setString( str );
      Q_EMIT responseAvailable( response );
  }

  Response response;
  response.setTag( tag() );
  response.setSuccess();
  response.setString( "TAGSTORE completed" );
  Q_EMIT responseAvailable( response );
  return true;
}
<commit_msg>TAGSTORE: Read the command until end, even when we are going to delete the tag<commit_after>/*
    Copyright (c) 2014 Daniel Vrátil <dvratil@redhat.com>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "tagstore.h"
#include "scope.h"
#include "tagfetchhelper.h"
#include "imapstreamparser.h"
#include "response.h"
#include "storage/datastore.h"
#include "libs/protocol_p.h"
#include "connection.h"

using namespace Akonadi::Server;

TagStore::TagStore()
  : Handler()
{
}

TagStore::~TagStore()
{
}

bool TagStore::parseStream()
{
  const qint64 tagId = m_streamParser->readNumber();

  if ( !m_streamParser->hasList() ) {
    failureResponse( "No changes to store" );
    return false;
  }

  Tag changedTag = Tag::retrieveById( tagId );
  if ( !changedTag.isValid() ) {
    throw HandlerException( "No such tag" );
  }

  // Retrieve all tag's attributes
  const TagAttribute::List attributes = TagAttribute::retrieveFiltered( TagAttribute::tagIdFullColumnName(), tagId );
  QMap<QByteArray,TagAttribute> attributesMap;
  Q_FOREACH ( const TagAttribute &attribute, attributes ) {
    attributesMap.insert( attribute.type(), attribute );
  }

  bool tagRemoved = false;
  m_streamParser->beginList();
  while ( !m_streamParser->atListEnd() ) {
    const QByteArray attr = m_streamParser->readString();

    if ( attr == AKONADI_PARAM_PARENT ) {
      const qint64 parent = m_streamParser->readNumber();
            changedTag.setParentId( parent );
    } else if ( attr == AKONADI_PARAM_GID ) {
      throw HandlerException( "Changing tag GID is not allowed" );
    } else if ( attr == AKONADI_PARAM_UID ) {
      throw HandlerException( "Changing tag UID is not allowed" );
    } else if ( attr == AKONADI_PARAM_MIMETYPE ) {
        const QString &typeName = m_streamParser->readUtf8String();
        TagType type = TagType::retrieveByName(typeName);
        if (!type.isValid()) {
            TagType newType;
            newType.setName(typeName);
            if (!newType.insert()) {
                throw HandlerException( "Failed to insert type" );
            }
            type = newType;
        }
        changedTag.setTagType(type);
    } else if ( attr == AKONADI_PARAM_REMOTEID ) {
        const QString &remoteId = m_streamParser->readUtf8String();
        if (!connection()->context()->resource().isValid()) {
            throw HandlerException( "Only resources can change the remoteid" );
        }
        TagRemoteIdResourceRelation::remove(TagRemoteIdResourceRelation::resourceIdFullColumnName(), connection()->context()->resource().id());

        if (!remoteId.isEmpty()) {
            TagRemoteIdResourceRelation remoteIdRelation;
            remoteIdRelation.setRemoteId(remoteId);
            remoteIdRelation.setResourceId(connection()->context()->resource().id());
            remoteIdRelation.setTag(changedTag);
            if (!remoteIdRelation.insert()) {
                throw HandlerException( "Failed to insert remotedid resource relation" );
            }
        } else {
            const int tagRidsCount = TagRemoteIdResourceRelation::count(TagRemoteIdResourceRelation::tagIdColumn(), changedTag.id());
            // We just removed the last RID of the tag, which means that no other
            // resource owns this tag, so we have to remove it to simulate tag
            // removal
            if (tagRidsCount == 0) {
                if (!DataStore::self()->removeTags(Tag::List() << changedTag)) {
                    throw HandlerException( "Failed to remove tag" );
                }
                tagRemoved = true;

                // We can't break here, we need to finish reading the command
            }
        }
    } else {
      if ( attr.startsWith( '-' ) ) {
        const QByteArray attrName = attr.mid( 1 );
        if ( attributesMap.contains( attrName ) ) {
          TagAttribute attribute = attributesMap.value( attrName );
          TagAttribute::remove( attribute.id() );
        }
      } else if ( attributesMap.contains( attr ) ) {
        const QByteArray value = m_streamParser->readString();
        TagAttribute attribute = attributesMap.value( attr );
        attribute.setValue( value );
        if (!attribute.update()) {
            throw HandlerException("Failed to update attribute");
        }
      } else {
        const QByteArray value = m_streamParser->readString();
        TagAttribute attribute;
        attribute.setTagId( tagId );
        attribute.setType( attr );
        attribute.setValue( value );
        if (!attribute.insert()) {
            throw HandlerException("Failed to insert attribute");
        }
      }
    }
  }

  if (!tagRemoved) {
      if (!changedTag.update()) {
        throw HandlerException( "Failed to store changes" );
      }
      DataStore::self()->notificationCollector()->tagChanged( changedTag );

      ImapSet set;
      set.add( QVector<qint64>() << tagId );
      TagFetchHelper helper( connection(), set );
      connect( &helper, SIGNAL(responseAvailable(Akonadi::Server::Response)),
               this, SIGNAL(responseAvailable(Akonadi::Server::Response)) );
      if ( !helper.fetchTags( AKONADI_CMD_TAGFETCH ) ) {
        return false;
      }
  } else {
      QByteArray str = QByteArray::number( tagId ) + " TAGREMOVE";
      Response response;
      response.setUntagged();
      response.setString( str );
      Q_EMIT responseAvailable( response );
  }

  Response response;
  response.setTag( tag() );
  response.setSuccess();
  response.setString( "TAGSTORE completed" );
  Q_EMIT responseAvailable( response );
  return true;
}
<|endoftext|>