<commit_before>#include <gtest/gtest.h>

#include <zinc/zincconfigure.h>
#include <zinc/core.h>
#include <zinc/field.h>
#include <zinc/fieldconstant.h>
#include <zinc/fieldimage.h>

#include <zinc/field.hpp>
#include <zinc/fieldcache.hpp>
#include <zinc/fieldconstant.hpp>
#include <zinc/fieldimage.hpp>
#include "zinctestsetup.hpp"
#include "zinctestsetupcpp.hpp"

#include "test_resources.h"

TEST(cmzn_field_image, create_evaluate)
{
	ZincTestSetup zinc;

	cmzn_field_id f1 = cmzn_field_module_create_image(zinc.fm);
	EXPECT_NE(static_cast<cmzn_field_id>(0), f1);

	cmzn_field_image_id im = cmzn_field_cast_image(f1);
	EXPECT_NE(static_cast<cmzn_field_image_id>(0), im);

	int result;
	EXPECT_EQ(CMZN_OK, result = cmzn_field_image_read_file(im, TestResources::getLocation(TestResources::FIELDIMAGE_BLOCKCOLOURS_RESOURCE)));
	int numberOfComponents = cmzn_field_get_number_of_components(f1);
	EXPECT_EQ(3, numberOfComponents);

	cmzn_field_id xi = cmzn_field_image_get_domain_field(im);
	EXPECT_NE(static_cast<cmzn_field_id>(0), f1);
	char *name = cmzn_field_get_name(xi);
	EXPECT_STREQ("xi", name);
	cmzn_deallocate(name);

	cmzn_field_cache_id cache = cmzn_field_module_create_cache(zinc.fm);
	EXPECT_NE(static_cast<cmzn_field_cache_id>(0), cache);
	double outRGB[3];
	const double xi1[3] = { 0.2, 0.8, 0.0 };
	const double expectedRGB1[3] = { 1.0, 128.0/255.0, 0.0 };
	EXPECT_EQ(CMZN_OK, result = cmzn_field_cache_set_field_real(cache, xi, 2, xi1));
	EXPECT_EQ(CMZN_OK, result = cmzn_field_evaluate_real(f1, cache, 3, outRGB));
	EXPECT_EQ(expectedRGB1[0], outRGB[0]);
	EXPECT_EQ(expectedRGB1[1], outRGB[1]);
	EXPECT_EQ(expectedRGB1[2], outRGB[2]);
	const double xi2[3] = { 0.75, 0.2, 0.0 };
	const double expectedRGB2[3] = { 192.0/255.0, 192.0/255.0, 192.0/255.0 };
	EXPECT_EQ(CMZN_OK, result = cmzn_field_cache_set_field_real(cache, xi, 2, xi2));
	EXPECT_EQ(CMZN_OK, result = cmzn_field_evaluate_real(f1, cache, 3, outRGB));
	EXPECT_EQ(expectedRGB2[0], outRGB[0]);
	EXPECT_EQ(expectedRGB2[1], outRGB[1]);
	EXPECT_EQ(expectedRGB2[2], outRGB[2]);
	cmzn_field_cache_destroy(&cache);

	double width = cmzn_field_image_get_texture_coordinate_width(im);
	ASSERT_DOUBLE_EQ(1.0, width);
	double height = cmzn_field_image_get_texture_coordinate_height(im);
	ASSERT_DOUBLE_EQ(1.0, height);
	double depth = cmzn_field_image_get_texture_coordinate_depth(im);
	ASSERT_DOUBLE_EQ(0.0, depth);
	double double_sizes[3];
	cmzn_field_image_get_texture_coordinate_sizes(im, 3, &double_sizes[0]);
	ASSERT_DOUBLE_EQ(1.0, double_sizes[0]);
	ASSERT_DOUBLE_EQ(1.0, double_sizes[1]);
	ASSERT_DOUBLE_EQ(0.0, double_sizes[2]);

	// test setting domain field and evaluation of image_from_source

	const double tempValues3[3] = { 0.0, 1.0, 2.0 };
	cmzn_field_id altDomainField = cmzn_field_module_create_constant(zinc.fm, 3, tempValues3);
	cmzn_field_set_name(altDomainField, "altDomainField");
	EXPECT_EQ(CMZN_OK, result = cmzn_field_image_set_domain_field(im, altDomainField));
	cmzn_field_id f2 = cmzn_field_module_create_image_from_source(zinc.fm, f1);
	EXPECT_NE(static_cast<cmzn_field_id>(0), f2);

	// check resolution is same as source field
	cmzn_field_image_id im2 = cmzn_field_cast_image(f2);
	int width_texels = cmzn_field_image_get_pixel_width(im2);
	EXPECT_EQ(32, width_texels);
	int height_texels = cmzn_field_image_get_pixel_height(im2);
	EXPECT_EQ(32, height_texels);
	int depth_texels = cmzn_field_image_get_pixel_depth(im2);
	EXPECT_EQ(1, depth_texels);
	int int_sizes[3];
	cmzn_field_image_get_pixel_sizes(im2, 3, &int_sizes[0]);
	EXPECT_EQ(32, int_sizes[0]);
	EXPECT_EQ(32, int_sizes[1]);
	EXPECT_EQ(1, int_sizes[2]);
	cmzn_field_image_destroy(&im2);

	cache = cmzn_field_module_create_cache(zinc.fm);
	EXPECT_NE(static_cast<cmzn_field_cache_id>(0), cache);
	EXPECT_EQ(CMZN_OK, result = cmzn_field_cache_set_field_real(cache, altDomainField, 3, xi1));
	EXPECT_EQ(CMZN_OK, result = cmzn_field_evaluate_real(f2, cache, 3, outRGB));
	EXPECT_EQ(expectedRGB1[0], outRGB[0]);
	EXPECT_EQ(expectedRGB1[1], outRGB[1]);
	EXPECT_EQ(expectedRGB1[2], outRGB[2]);
	cmzn_field_cache_destroy(&cache);

	cmzn_field_destroy(&f2);
	cmzn_field_destroy(&altDomainField);
	cmzn_field_destroy(&xi);
	cmzn_field_image_destroy(&im);
	cmzn_field_destroy(&f1);
}

TEST(ZincFieldImage, create_evaluate)
{
	ZincTestSetupCpp zinc;

	FieldImage im = zinc.fm.createImage();
	EXPECT_TRUE(im.isValid());

	int result;
	EXPECT_EQ(OK, result = im.readFile(TestResources::getLocation(TestResources::FIELDIMAGE_BLOCKCOLOURS_RESOURCE)));
	int numberOfComponents = im.getNumberOfComponents();
	EXPECT_EQ(3, numberOfComponents);

	Field xi = im.getDomainField();
	EXPECT_TRUE(xi.isValid());
	char *name = xi.getName();
	EXPECT_STREQ("xi", name);
	cmzn_deallocate(name);

	FieldCache cache = zinc.fm.createCache();
	EXPECT_TRUE(cache.isValid());
	double outRGB[3];
	const double xi1[3] = { 0.2, 0.8, 0.0 };
	const double expectedRGB1[3] = { 1.0, 128.0/255.0, 0.0 };
	EXPECT_EQ(OK, result = cache.setFieldReal(xi, 2, xi1));
	EXPECT_EQ(OK, result = im.evaluateReal(cache, 3, outRGB));
	EXPECT_EQ(expectedRGB1[0], outRGB[0]);
	EXPECT_EQ(expectedRGB1[1], outRGB[1]);
	EXPECT_EQ(expectedRGB1[2], outRGB[2]);
	const double xi2[3] = { 0.75, 0.2, 0.0 };
	const double expectedRGB2[3] = { 192.0/255.0, 192.0/255.0, 192.0/255.0 };
	EXPECT_EQ(OK, result = cache.setFieldReal(xi, 2, xi2));
	EXPECT_EQ(OK, result = im.evaluateReal(cache, 3, outRGB));
	EXPECT_EQ(expectedRGB2[0], outRGB[0]);
	EXPECT_EQ(expectedRGB2[1], outRGB[1]);
	EXPECT_EQ(expectedRGB2[2], outRGB[2]);

	double width = im.getTextureCoordinateWidth();
	ASSERT_DOUBLE_EQ(1.0, width);
	double height = im.getTextureCoordinateHeight();
	ASSERT_DOUBLE_EQ(1.0, height);
	double depth = im.getTextureCoordinateDepth();
	ASSERT_DOUBLE_EQ(0.0, depth);
	double double_sizes[3];
	im.getTextureCoordinateSizes(3, &double_sizes[0]);
	ASSERT_DOUBLE_EQ(1.0, double_sizes[0]);
	ASSERT_DOUBLE_EQ(1.0, double_sizes[1]);
	ASSERT_DOUBLE_EQ(0.0, double_sizes[2]);

	// test setting domain field and evaluation of imageFromSource

	const double tempValues3[3] = { 0.0, 1.0, 2.0 };
	FieldConstant altDomainField = zinc.fm.createConstant(3, tempValues3);
	altDomainField.setName("altDomainField");
	EXPECT_EQ(OK, result = im.setDomainField(altDomainField));
	FieldImage im2 = zinc.fm.createImageFromSource(im);
	EXPECT_TRUE(im2.isValid());

	// check resolution is same as source field
	int width_texels = im2.getPixelWidth();
	EXPECT_EQ(32, width_texels);
	int height_texels = im2.getPixelHeight();
	EXPECT_EQ(32, height_texels);
	int depth_texels = im2.getPixelDepth();
	EXPECT_EQ(1, depth_texels);
	int int_sizes[3];
	im2.getPixelSizes(3, &int_sizes[0]);
	EXPECT_EQ(32, int_sizes[0]);
	EXPECT_EQ(32, int_sizes[1]);
	EXPECT_EQ(1, int_sizes[2]);

	cache = zinc.fm.createCache();
	EXPECT_TRUE(cache.isValid());
	EXPECT_EQ(OK, result = cache.setFieldReal(altDomainField, 3, xi1));
	EXPECT_EQ(OK, result = im2.evaluateReal(cache, 3, outRGB));
	EXPECT_EQ(expectedRGB1[0], outRGB[0]);
	EXPECT_EQ(expectedRGB1[1], outRGB[1]);
	EXPECT_EQ(expectedRGB1[2], outRGB[2]);
}
<commit_msg>Updated unit test as image pixel APIs have been renamed. https://tracker.physiomeproject.org/show_bug.cgi?id=3627<commit_after>#include <gtest/gtest.h>

#include <zinc/zincconfigure.h>
#include <zinc/core.h>
#include <zinc/field.h>
#include <zinc/fieldconstant.h>
#include <zinc/fieldimage.h>

#include <zinc/field.hpp>
#include <zinc/fieldcache.hpp>
#include <zinc/fieldconstant.hpp>
#include <zinc/fieldimage.hpp>
#include "zinctestsetup.hpp"
#include "zinctestsetupcpp.hpp"

#include "test_resources.h"

TEST(cmzn_field_image, create_evaluate)
{
	ZincTestSetup zinc;

	cmzn_field_id f1 = cmzn_field_module_create_image(zinc.fm);
	EXPECT_NE(static_cast<cmzn_field_id>(0), f1);

	cmzn_field_image_id im = cmzn_field_cast_image(f1);
	EXPECT_NE(static_cast<cmzn_field_image_id>(0), im);

	int result;
	EXPECT_EQ(CMZN_OK, result = cmzn_field_image_read_file(im, TestResources::getLocation(TestResources::FIELDIMAGE_BLOCKCOLOURS_RESOURCE)));
	int numberOfComponents = cmzn_field_get_number_of_components(f1);
	EXPECT_EQ(3, numberOfComponents);

	cmzn_field_id xi = cmzn_field_image_get_domain_field(im);
	EXPECT_NE(static_cast<cmzn_field_id>(0), f1);
	char *name = cmzn_field_get_name(xi);
	EXPECT_STREQ("xi", name);
	cmzn_deallocate(name);

	cmzn_field_cache_id cache = cmzn_field_module_create_cache(zinc.fm);
	EXPECT_NE(static_cast<cmzn_field_cache_id>(0), cache);
	double outRGB[3];
	const double xi1[3] = { 0.2, 0.8, 0.0 };
	const double expectedRGB1[3] = { 1.0, 128.0/255.0, 0.0 };
	EXPECT_EQ(CMZN_OK, result = cmzn_field_cache_set_field_real(cache, xi, 2, xi1));
	EXPECT_EQ(CMZN_OK, result = cmzn_field_evaluate_real(f1, cache, 3, outRGB));
	EXPECT_EQ(expectedRGB1[0], outRGB[0]);
	EXPECT_EQ(expectedRGB1[1], outRGB[1]);
	EXPECT_EQ(expectedRGB1[2], outRGB[2]);
	const double xi2[3] = { 0.75, 0.2, 0.0 };
	const double expectedRGB2[3] = { 192.0/255.0, 192.0/255.0, 192.0/255.0 };
	EXPECT_EQ(CMZN_OK, result = cmzn_field_cache_set_field_real(cache, xi, 2, xi2));
	EXPECT_EQ(CMZN_OK, result = cmzn_field_evaluate_real(f1, cache, 3, outRGB));
	EXPECT_EQ(expectedRGB2[0], outRGB[0]);
	EXPECT_EQ(expectedRGB2[1], outRGB[1]);
	EXPECT_EQ(expectedRGB2[2], outRGB[2]);
	cmzn_field_cache_destroy(&cache);

	double width = cmzn_field_image_get_texture_coordinate_width(im);
	ASSERT_DOUBLE_EQ(1.0, width);
	double height = cmzn_field_image_get_texture_coordinate_height(im);
	ASSERT_DOUBLE_EQ(1.0, height);
	double depth = cmzn_field_image_get_texture_coordinate_depth(im);
	ASSERT_DOUBLE_EQ(0.0, depth);
	double double_sizes[3];
	cmzn_field_image_get_texture_coordinate_sizes(im, 3, &double_sizes[0]);
	ASSERT_DOUBLE_EQ(1.0, double_sizes[0]);
	ASSERT_DOUBLE_EQ(1.0, double_sizes[1]);
	ASSERT_DOUBLE_EQ(0.0, double_sizes[2]);

	// test setting domain field and evaluation of image_from_source

	const double tempValues3[3] = { 0.0, 1.0, 2.0 };
	cmzn_field_id altDomainField = cmzn_field_module_create_constant(zinc.fm, 3, tempValues3);
	cmzn_field_set_name(altDomainField, "altDomainField");
	EXPECT_EQ(CMZN_OK, result = cmzn_field_image_set_domain_field(im, altDomainField));
	cmzn_field_id f2 = cmzn_field_module_create_image_from_source(zinc.fm, f1);
	EXPECT_NE(static_cast<cmzn_field_id>(0), f2);

	// check resolution is same as source field
	cmzn_field_image_id im2 = cmzn_field_cast_image(f2);
	int width_texels = cmzn_field_image_get_width_in_pixels(im2);
	EXPECT_EQ(32, width_texels);
	int height_texels = cmzn_field_image_get_height_in_pixels(im2);
	EXPECT_EQ(32, height_texels);
	int depth_texels = cmzn_field_image_get_depth_in_pixels(im2);
	EXPECT_EQ(1, depth_texels);
	int int_sizes[3];
	cmzn_field_image_get_size_in_pixels(im2, 3, &int_sizes[0]);
	EXPECT_EQ(32, int_sizes[0]);
	EXPECT_EQ(32, int_sizes[1]);
	EXPECT_EQ(1, int_sizes[2]);
	cmzn_field_image_destroy(&im2);

	cache = cmzn_field_module_create_cache(zinc.fm);
	EXPECT_NE(static_cast<cmzn_field_cache_id>(0), cache);
	EXPECT_EQ(CMZN_OK, result = cmzn_field_cache_set_field_real(cache, altDomainField, 3, xi1));
	EXPECT_EQ(CMZN_OK, result = cmzn_field_evaluate_real(f2, cache, 3, outRGB));
	EXPECT_EQ(expectedRGB1[0], outRGB[0]);
	EXPECT_EQ(expectedRGB1[1], outRGB[1]);
	EXPECT_EQ(expectedRGB1[2], outRGB[2]);
	cmzn_field_cache_destroy(&cache);

	cmzn_field_destroy(&f2);
	cmzn_field_destroy(&altDomainField);
	cmzn_field_destroy(&xi);
	cmzn_field_image_destroy(&im);
	cmzn_field_destroy(&f1);
}

TEST(ZincFieldImage, create_evaluate)
{
	ZincTestSetupCpp zinc;

	FieldImage im = zinc.fm.createImage();
	EXPECT_TRUE(im.isValid());

	int result;
	EXPECT_EQ(OK, result = im.readFile(TestResources::getLocation(TestResources::FIELDIMAGE_BLOCKCOLOURS_RESOURCE)));
	int numberOfComponents = im.getNumberOfComponents();
	EXPECT_EQ(3, numberOfComponents);

	Field xi = im.getDomainField();
	EXPECT_TRUE(xi.isValid());
	char *name = xi.getName();
	EXPECT_STREQ("xi", name);
	cmzn_deallocate(name);

	FieldCache cache = zinc.fm.createCache();
	EXPECT_TRUE(cache.isValid());
	double outRGB[3];
	const double xi1[3] = { 0.2, 0.8, 0.0 };
	const double expectedRGB1[3] = { 1.0, 128.0/255.0, 0.0 };
	EXPECT_EQ(OK, result = cache.setFieldReal(xi, 2, xi1));
	EXPECT_EQ(OK, result = im.evaluateReal(cache, 3, outRGB));
	EXPECT_EQ(expectedRGB1[0], outRGB[0]);
	EXPECT_EQ(expectedRGB1[1], outRGB[1]);
	EXPECT_EQ(expectedRGB1[2], outRGB[2]);
	const double xi2[3] = { 0.75, 0.2, 0.0 };
	const double expectedRGB2[3] = { 192.0/255.0, 192.0/255.0, 192.0/255.0 };
	EXPECT_EQ(OK, result = cache.setFieldReal(xi, 2, xi2));
	EXPECT_EQ(OK, result = im.evaluateReal(cache, 3, outRGB));
	EXPECT_EQ(expectedRGB2[0], outRGB[0]);
	EXPECT_EQ(expectedRGB2[1], outRGB[1]);
	EXPECT_EQ(expectedRGB2[2], outRGB[2]);

	double width = im.getTextureCoordinateWidth();
	ASSERT_DOUBLE_EQ(1.0, width);
	double height = im.getTextureCoordinateHeight();
	ASSERT_DOUBLE_EQ(1.0, height);
	double depth = im.getTextureCoordinateDepth();
	ASSERT_DOUBLE_EQ(0.0, depth);
	double double_sizes[3];
	im.getTextureCoordinateSizes(3, &double_sizes[0]);
	ASSERT_DOUBLE_EQ(1.0, double_sizes[0]);
	ASSERT_DOUBLE_EQ(1.0, double_sizes[1]);
	ASSERT_DOUBLE_EQ(0.0, double_sizes[2]);

	// test setting domain field and evaluation of imageFromSource

	const double tempValues3[3] = { 0.0, 1.0, 2.0 };
	FieldConstant altDomainField = zinc.fm.createConstant(3, tempValues3);
	altDomainField.setName("altDomainField");
	EXPECT_EQ(OK, result = im.setDomainField(altDomainField));
	FieldImage im2 = zinc.fm.createImageFromSource(im);
	EXPECT_TRUE(im2.isValid());

	// check resolution is same as source field
	int width_texels = im2.getWidthInPixels();
	EXPECT_EQ(32, width_texels);
	int height_texels = im2.getHeightInPixels();
	EXPECT_EQ(32, height_texels);
	int depth_texels = im2.getDepthInPixels();
	EXPECT_EQ(1, depth_texels);
	int int_sizes[3];
	im2.getSizeInPixels(3, &int_sizes[0]);
	EXPECT_EQ(32, int_sizes[0]);
	EXPECT_EQ(32, int_sizes[1]);
	EXPECT_EQ(1, int_sizes[2]);

	cache = zinc.fm.createCache();
	EXPECT_TRUE(cache.isValid());
	EXPECT_EQ(OK, result = cache.setFieldReal(altDomainField, 3, xi1));
	EXPECT_EQ(OK, result = im2.evaluateReal(cache, 3, outRGB));
	EXPECT_EQ(expectedRGB1[0], outRGB[0]);
	EXPECT_EQ(expectedRGB1[1], outRGB[1]);
	EXPECT_EQ(expectedRGB1[2], outRGB[2]);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fuchar.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:30:03 $
 *
 *  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 SD_FU_CHAR_HXX
#define SD_FU_CHAR_HXX

#ifndef SD_FU_POOR_HXX
#include "fupoor.hxx"
#endif

namespace sd {

class FuChar
    : public FuPoor
{
public:
    TYPEINFO();

    FuChar (
        ViewShell* pViewSh,
        ::sd::Window* pWin,
        ::sd::View* pView,
        SdDrawDocument* pDoc,
        SfxRequest& rReq);
    virtual ~FuChar (void) {}

    virtual void Activate() {}         // Function aktivieren
    virtual void Deactivate() {}           // Function deaktivieren
};

} // end of namespace sd

#endif

<commit_msg>INTEGRATION: CWS impressfunctions (1.3.40); FILE MERGED 2005/10/28 10:56:37 cl 1.3.40.1: #125341# reworked FuPoor classes to use refcounting<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fuchar.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-12-14 17:07:51 $
 *
 *  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 SD_FU_CHAR_HXX
#define SD_FU_CHAR_HXX

#ifndef SD_FU_POOR_HXX
#include "fupoor.hxx"
#endif

namespace sd {

class FuChar
    : public FuPoor
{
public:
    TYPEINFO();

    static FunctionReference Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq );

    virtual void DoExecute( SfxRequest& rReq );

    virtual void Activate();
    virtual void Deactivate();

private:
    FuChar (
        ViewShell* pViewSh,
        ::sd::Window* pWin,
        ::sd::View* pView,
        SdDrawDocument* pDoc,
        SfxRequest& rReq);
};

} // end of namespace sd

#endif

<|endoftext|>


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

#include "Debug.h"
#include "RenderTarget.h"
#include "ParameterInterpolator.h"
#include "Rasterizer.h"
#include "PixelShader.h"
#include "utils.h"

#define COLOR_SHADER 1

const int kMaxTileIndex = (640 / 64) * ((480 / 64) + 1);
int nextTileIndex = 0;

struct Vertex
{
	float coord[3];
	float params[kMaxParams];
};

class ColorShader : public PixelShader
{
public:
	ColorShader(ParameterInterpolator *interp, RenderTarget *target)
		:	PixelShader(interp, target)
	{}

	virtual void shadePixels(const vecf16 inParams[16], vecf16 outParams[16],
		unsigned short mask);
};

void ColorShader::shadePixels(const vecf16 inParams[16], vecf16 outParams[16],
	unsigned short mask)
{
	for (int i = 0; i < 3; i++)
		outParams[i] = inParams[i];
}

class CheckerboardShader : public PixelShader
{
public:
	CheckerboardShader(ParameterInterpolator *interp, RenderTarget *target)
		:	PixelShader(interp, target)
	{}

	virtual void shadePixels(const vecf16 inParams[16], vecf16 outParams[16],
		unsigned short mask);
};

void CheckerboardShader::shadePixels(const vecf16 inParams[16], vecf16 outParams[16],
	unsigned short mask)
{
	veci16 u = ((__builtin_vp_vftoi(inParams[0] * __builtin_vp_makevectorf(65535.0)))
		>> __builtin_vp_makevectori(10)) & __builtin_vp_makevectori(1);
	veci16 v = ((__builtin_vp_vftoi(inParams[1] * __builtin_vp_makevectorf(65535.0)))
		>> __builtin_vp_makevectori(10)) & __builtin_vp_makevectori(1);

	veci16 color = u ^ v;

	outParams[0] = outParams[1] = outParams[2] = __builtin_vp_vitof(color);
}

const int kFbWidth = 640;
const int kFbHeight = 480;

int main()
{
	Rasterizer rasterizer;
	RenderTarget renderTarget(0x100000, kFbWidth, kFbHeight);
	ParameterInterpolator interp(kFbWidth, kFbHeight);
#if COLOR_SHADER
	ColorShader shader(&interp, &renderTarget);
#else
	CheckerboardShader shader(&interp, &renderTarget);
#endif

	Vertex vertices[3] = {
#if COLOR_SHADER
		{ { 0.3, 0.1, 0.5 }, { 1.0, 0.0, 0.0 } },
		{ { 0.9, 0.5, 0.4 }, { 0.0, 1.0, 0.0 } },
		{ { 0.1, 0.9, 0.3 }, { 0.0, 0.0, 1.0 } },
#else
		{ { 0.3, 0.1, 0.6 }, { 0.0, 0.0 } },
		{ { 0.9, 0.5, 0.4 }, { 0.0, 1.0 } },
		{ { 0.1, 0.9, 0.1 }, { 1.0, 1.0 } },
#endif
	};

	while (nextTileIndex < kMaxTileIndex)
	{
		int myTileIndex = __sync_fetch_and_add(&nextTileIndex, 1);
		if (myTileIndex >= kMaxTileIndex)
			break;

		unsigned int tileX, tileY;
		udiv(myTileIndex, 10, tileY, tileX);

		interp.setUpTriangle(
			vertices[0].coord[0], vertices[0].coord[1], vertices[0].coord[2],
			vertices[1].coord[0], vertices[1].coord[1], vertices[1].coord[2],
			vertices[2].coord[0], vertices[2].coord[1], vertices[2].coord[2]);

		for (int param = 0; param < 3; param++)
		{
			interp.setUpParam(param, vertices[0].params[param],
				vertices[1].params[param], vertices[2].params[param]);
		}

		rasterizer.rasterizeTriangle(&shader, tileX * 64, tileY * 64,
			(int)(vertices[0].coord[0] * kFbWidth),
			(int)(vertices[0].coord[1] * kFbHeight),
			(int)(vertices[1].coord[0] * kFbWidth),
			(int)(vertices[1].coord[1] * kFbHeight),
			(int)(vertices[2].coord[0] * kFbWidth),
			(int)(vertices[2].coord[1] * kFbHeight));
	}

	return 0;
}

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

#include "Debug.h"
#include "RenderTarget.h"
#include "ParameterInterpolator.h"
#include "Rasterizer.h"
#include "PixelShader.h"
#include "utils.h"

#define COLOR_SHADER 1

const int kMaxTileIndex = (640 / 64) * ((480 / 64) + 1);
int nextTileIndex = 0;

struct Vertex
{
	float coord[3];
	float params[kMaxParams];
};

class ColorShader : public PixelShader
{
public:
	ColorShader(ParameterInterpolator *interp, RenderTarget *target)
		:	PixelShader(interp, target)
	{}

	virtual void shadePixels(const vecf16 inParams[16], vecf16 outParams[16],
		unsigned short mask);
};

void ColorShader::shadePixels(const vecf16 inParams[16], vecf16 outParams[16],
	unsigned short mask)
{
	for (int i = 0; i < 3; i++)
		outParams[i] = inParams[i];
}

class CheckerboardShader : public PixelShader
{
public:
	CheckerboardShader(ParameterInterpolator *interp, RenderTarget *target)
		:	PixelShader(interp, target)
	{}

	virtual void shadePixels(const vecf16 inParams[16], vecf16 outParams[16],
		unsigned short mask);
};

void CheckerboardShader::shadePixels(const vecf16 inParams[16], vecf16 outParams[16],
	unsigned short mask)
{
	veci16 u = ((__builtin_vp_vftoi(inParams[0] * __builtin_vp_makevectorf(65535.0)))
		>> __builtin_vp_makevectori(10)) & __builtin_vp_makevectori(1);
	veci16 v = ((__builtin_vp_vftoi(inParams[1] * __builtin_vp_makevectorf(65535.0)))
		>> __builtin_vp_makevectori(10)) & __builtin_vp_makevectori(1);

	veci16 color = u ^ v;

	outParams[0] = outParams[1] = outParams[2] = __builtin_vp_vitof(color);
}

const int kFbWidth = 640;
const int kFbHeight = 480;

//
// All threads start execution here
//
int main()
{
	Rasterizer rasterizer;
	RenderTarget renderTarget(0x100000, kFbWidth, kFbHeight);
	ParameterInterpolator interp(kFbWidth, kFbHeight);
#if COLOR_SHADER
	ColorShader shader(&interp, &renderTarget);
#else
	CheckerboardShader shader(&interp, &renderTarget);
#endif

	Vertex vertices[3] = {
#if COLOR_SHADER
		{ { 0.3, 0.1, 0.5 }, { 1.0, 0.0, 0.0 } },
		{ { 0.9, 0.5, 0.4 }, { 0.0, 1.0, 0.0 } },
		{ { 0.1, 0.9, 0.3 }, { 0.0, 0.0, 1.0 } },
#else
		{ { 0.3, 0.1, 0.6 }, { 0.0, 0.0 } },
		{ { 0.9, 0.5, 0.4 }, { 0.0, 1.0 } },
		{ { 0.1, 0.9, 0.1 }, { 1.0, 1.0 } },
#endif
	};

	while (nextTileIndex < kMaxTileIndex)
	{
		// Grab the next available tile to begin working on.
		int myTileIndex = __sync_fetch_and_add(&nextTileIndex, 1);
		if (myTileIndex >= kMaxTileIndex)
			break;

		unsigned int tileX, tileY;
		udiv(myTileIndex, 10, tileY, tileX);

		interp.setUpTriangle(
			vertices[0].coord[0], vertices[0].coord[1], vertices[0].coord[2],
			vertices[1].coord[0], vertices[1].coord[1], vertices[1].coord[2],
			vertices[2].coord[0], vertices[2].coord[1], vertices[2].coord[2]);

		for (int param = 0; param < 3; param++)
		{
			interp.setUpParam(param, vertices[0].params[param],
				vertices[1].params[param], vertices[2].params[param]);
		}

		// Fill a 64x64 tile
		rasterizer.rasterizeTriangle(&shader, tileX * 64, tileY * 64,
			(int)(vertices[0].coord[0] * kFbWidth),
			(int)(vertices[0].coord[1] * kFbHeight),
			(int)(vertices[1].coord[0] * kFbWidth),
			(int)(vertices[1].coord[1] * kFbHeight),
			(int)(vertices[2].coord[0] * kFbWidth),
			(int)(vertices[2].coord[1] * kFbHeight));
	}

	return 0;
}

Debug Debug::debug;
<|endoftext|>


<commit_before>/*
  Q Light Controller - Fixture Editor
  editmode.cpp

  Copyright (C) Heikki Junnila

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include <QTreeWidgetItem>
#include <QInputDialog>
#include <QHeaderView>
#include <QMessageBox>
#include <QTreeWidget>
#include <QPushButton>
#include <QComboBox>
#include <QLineEdit>
#include <QSettings>
#include <QSpinBox>
#include <QPoint>
#include <QDebug>
#include <QSize>
#include <QAction>

#include "addchannelsdialog.h"
#include "qlcfixturemode.h"
#include "qlcfixturehead.h"
#include "qlcfixturedef.h"
#include "qlcphysical.h"
#include "qlcchannel.h"

#include "editphysical.h"
#include "editmode.h"
#include "edithead.h"
#include "util.h"
#include "app.h"

#define KSettingsGeometry "editmode/geometry"

#define PROP_PTR Qt::UserRole
#define COL_NUM  0
#define COL_NAME 1
#define COL_ACTS_ON 2

EditMode::EditMode(QWidget *parent, QLCFixtureMode *mode)
    : QDialog(parent)
    , m_mode(new QLCFixtureMode(mode->fixtureDef(), mode))
{
    Q_ASSERT(mode != NULL);
    setupUi(this);
    init();
}

EditMode::EditMode(QWidget *parent, QLCFixtureDef *fixtureDef)
    : QDialog(parent)
    , m_mode(new QLCFixtureMode(fixtureDef))
{
    Q_ASSERT(fixtureDef != NULL);
    setupUi(this);
    init();
}

EditMode::~EditMode()
{
    QSettings settings;
    settings.setValue(KSettingsGeometry, saveGeometry());

    delete m_mode;
}

void EditMode::init()
{
    /* Channels page */
    connect(m_addChannelButton, SIGNAL(clicked()), this, SLOT(slotAddChannelClicked()));
    connect(m_removeChannelButton, SIGNAL(clicked()), this, SLOT(slotRemoveChannelClicked()));
    connect(m_raiseChannelButton, SIGNAL(clicked()), this, SLOT(slotRaiseChannelClicked()));
    connect(m_lowerChannelButton, SIGNAL(clicked()), this, SLOT(slotLowerChannelClicked()));

    m_modeNameEdit->setText(m_mode->name());
    m_modeNameEdit->setValidator(CAPS_VALIDATOR(this));
    refreshChannelList();

    /* Heads page */
    connect(m_addHeadButton, SIGNAL(clicked()), this, SLOT(slotAddHeadClicked()));
    connect(m_removeHeadButton, SIGNAL(clicked()), this, SLOT(slotRemoveHeadClicked()));
    connect(m_editHeadButton, SIGNAL(clicked()), this, SLOT(slotEditHeadClicked()));
    connect(m_raiseHeadButton, SIGNAL(clicked()), this, SLOT(slotRaiseHeadClicked()));
    connect(m_lowerHeadButton, SIGNAL(clicked()), this, SLOT(slotLowerHeadClicked()));

    refreshHeadList();

    /* Physical page */
    m_phyEdit = new EditPhysical(m_mode->physical(), this);
    m_phyEdit->show();
    physicalLayout->addWidget(m_phyEdit);

    if (m_mode->useGlobalPhysical() == false)
        m_overridePhyCheck->setChecked(true);
    slotPhysicalModeChanged();

    connect(m_globalPhyCheck, SIGNAL(clicked(bool)), this, SLOT(slotPhysicalModeChanged()));
    connect(m_overridePhyCheck, SIGNAL(clicked(bool)), this, SLOT(slotPhysicalModeChanged()));
    /* Forward copy/paste requests up to reach the main FixtureEditor clipboard */
    connect(m_phyEdit, SIGNAL(copyToClipboard(QLCPhysical)), this, SIGNAL(copyToClipboard(QLCPhysical)));
    connect(m_phyEdit, SIGNAL(requestPasteFromClipboard()), this, SIGNAL(requestPasteFromClipboard()));

    // Close shortcut
    QAction *action = new QAction(this);
    action->setShortcut(QKeySequence(QKeySequence::Close));
    connect(action, SIGNAL(triggered(bool)), this, SLOT(reject()));
    addAction(action);

    // Geometry
    QSettings settings;
    QVariant var = settings.value(KSettingsGeometry);
    if (var.isValid() == true)
        restoreGeometry(var.toByteArray());
}

QLCFixtureMode *EditMode::mode()
{
    return m_mode;
}

/****************************************************************************
 * Channels page
 ****************************************************************************/

void EditMode::slotAddChannelClicked()
{
    AddChannelsDialog ach(m_mode->fixtureDef()->channels(), m_mode->channels());
    if (ach.exec() != QDialog::Accepted)
        return;

    QList<QLCChannel *> newChannelList = ach.getModeChannelsList();

    // clear the previous list
    m_mode->removeAllChannels();

    // Append the channels
    foreach (QLCChannel *ch, newChannelList)
        m_mode->insertChannel(ch, m_mode->channels().size());

    // Easier to refresh the whole list
    refreshChannelList();
}

void EditMode::slotRemoveChannelClicked()
{
    QLCChannel *ch = currentChannel();

    if (ch != NULL)
    {
        QTreeWidgetItem *item;
        QString select;

        // Pick the item above or below to be selected next
        item = m_channelList->itemAbove(m_channelList->currentItem());
        if (item == NULL)
            item = m_channelList->itemBelow(m_channelList->currentItem());
        if (item != NULL)
            select = item->text(COL_NAME);

        // Remove the channel and the listview item
        m_mode->removeChannel(ch);
        delete m_channelList->currentItem();

        // Easier to refresh the whole list than to decrement all
        // channel numbers after the inserted item
        refreshChannelList();

        // Select another channel
        selectChannel(select);
    }
}

void EditMode::slotRaiseChannelClicked()
{
    QLCChannel *ch = currentChannel();
    int index = 0;

    if (ch == NULL)
        return;

    index = m_mode->channelNumber(ch) - 1;

    // Don't move beyond the beginning of the list
    if (index < 0)
        return;

    m_mode->removeChannel(ch);
    m_mode->insertChannel(ch, index);

    refreshChannelList();
    selectChannel(ch->name());
}

void EditMode::slotLowerChannelClicked()
{
    QLCChannel *ch = currentChannel();
    int index = 0;

    if (ch == NULL)
        return;

    index = m_mode->channelNumber(ch) + 1;

    // Don't move beyond the end of the list
    if (index >= m_mode->channels().size())
        return;

    m_mode->removeChannel(ch);
    m_mode->insertChannel(ch, index);

    refreshChannelList();
    selectChannel(ch->name());
}

void EditMode::slotActsOnChannelChanged(QLCChannel *newActsOnChannel)
{
    QLCChannel *channel = currentChannel();

    if (channel == NULL)
        return;

    m_mode->updateActsOnChannel(channel, newActsOnChannel);
    refreshChannelList();
}

void EditMode::refreshChannelList()
{
    m_channelList->clear();

    for (int i = 0; i < m_mode->channels().size(); i++)
    {
        QTreeWidgetItem *item = new QTreeWidgetItem(m_channelList);
        QLCChannel *ch = m_mode->channel(i);

        int actsOnChannelIndex = m_mode->channels().indexOf(m_mode->actsOnChannelsList().value(ch));

        Q_ASSERT(ch != NULL);

        QString str;
        item->setText(COL_NUM, str.asprintf("%.3d", (i + 1)));
        item->setText(COL_NAME, ch->name());
        item->setIcon(COL_NAME, ch->getIcon());
        item->setData(COL_NAME, PROP_PTR, (qulonglong) ch);

        QStringList comboList;

        comboList << "-";

        for (int index = 0; index < m_mode->channels().size(); index++)
        {
            QLCChannel *currentChannel = m_mode->channels().at(index);
            comboList << QString::number(index + 1) + " - " + currentChannel->name();
        }

        QComboBox *comboBox = new QComboBox(this);
        comboBox->addItems(comboList);

        if (actsOnChannelIndex >= 0)
            comboBox->setCurrentIndex(actsOnChannelIndex + 1);
        else
            comboBox->setCurrentIndex(0);

        m_channelList->setItemWidget(item, COL_ACTS_ON, comboBox);

        connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setActsOnChannel(int)));
    }
    m_channelList->header()->resizeSections(QHeaderView::ResizeToContents);
}

QLCChannel* EditMode::currentChannel()
{
    QTreeWidgetItem *item;
    QLCChannel *ch = NULL;

    // Convert the string-form ulong to a QLCChannel pointer and return it
    item = m_channelList->currentItem();
    if (item != NULL)
        ch = (QLCChannel*)item->data(COL_NAME, PROP_PTR).toULongLong();

    return ch;
}

void EditMode::selectChannel(const QString &name)
{
    QTreeWidgetItemIterator it(m_channelList);
    while (*it != NULL)
    {
        if ((*it)->text(COL_NAME) == name)
        {
            m_channelList->setCurrentItem((*it));
            break;
        }

        ++it;
    }
}

void EditMode::setActsOnChannel(int index)
{
    int channelNumber = index - 1;

    QLCChannel *actsOnChannel = NULL;

    if (channelNumber >= 0)
        actsOnChannel = m_mode->channels().at(channelNumber);

    slotActsOnChannelChanged(actsOnChannel);
}

/****************************************************************************
 * Heads page
 ****************************************************************************/

void EditMode::slotAddHeadClicked()
{
    EditHead eh(this, QLCFixtureHead(), m_mode);
    if (eh.exec() == QDialog::Accepted)
    {
        m_mode->insertHead(-1, eh.head());
        refreshHeadList();
    }
}

void EditMode::slotRemoveHeadClicked()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return;

    int index = m_headList->indexOfTopLevelItem(item);
    m_mode->removeHead(index);
    refreshHeadList();
}

void EditMode::slotEditHeadClicked()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return;

    EditHead eh(this, currentHead(), m_mode);
    if (eh.exec() == QDialog::Accepted)
    {
        int index = m_headList->indexOfTopLevelItem(item);
        m_mode->replaceHead(index, eh.head());
        refreshHeadList();
    }
}

void EditMode::slotRaiseHeadClicked()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return;

    int index = m_headList->indexOfTopLevelItem(item);

    // Don't move beyond the beginning of the list
    if ((index - 1) < 0)
        return;

    QLCFixtureHead head = currentHead();
    m_mode->removeHead(index);
    m_mode->insertHead(index - 1, head);

    refreshHeadList();
    selectHead(index - 1);
}

void EditMode::slotLowerHeadClicked()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return;

    int index = m_headList->indexOfTopLevelItem(item);

    // Don't move beyond the end of the list
    if ((index + 1) >= m_mode->heads().size())
        return;

    QLCFixtureHead head = currentHead();
    m_mode->removeHead(index);
    m_mode->insertHead(index + 1, head);

    refreshHeadList();
    selectHead(index + 1);
}

void EditMode::refreshHeadList()
{
    m_headList->clear();

    for (int i = 0; i < m_mode->heads().size(); i++)
    {
        QTreeWidgetItem *item = new QTreeWidgetItem(m_headList);
        QLCFixtureHead head = m_mode->heads().at(i);
        QList <quint32> channels(head.channels());
        QString summary;

        std::sort(channels.begin(), channels.end());

        QListIterator <quint32> it(channels);
        while (it.hasNext() == true)
        {
            quint32 chnum = it.next();
            const QLCChannel *ch = m_mode->channel(chnum);
            QTreeWidgetItem *chitem = new QTreeWidgetItem(item);
            if (ch != NULL)
                chitem->setText(0, QString("%1: %2").arg(chnum + 1).arg(ch->name()));
            else
                chitem->setText(0, QString("%1: INVALID!"));
            chitem->setFlags(Qt::NoItemFlags); // Disable channel selection inside heads

            summary += QString::number(chnum + 1);
            if (it.hasNext() == true)
                summary += QString(", ");
        }

        item->setText(0, QString("Head %1 (%2)").arg(i + 1).arg(summary));
    }
    m_headList->resizeColumnToContents(0);
}

QLCFixtureHead EditMode::currentHead()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return QLCFixtureHead();

    int index = m_headList->indexOfTopLevelItem(item);
    return m_mode->heads().at(index);
}

void EditMode::selectHead(int index)
{
    if (index >= m_headList->topLevelItemCount())
        return;

    QTreeWidgetItem *item = m_headList->topLevelItem(index);
    m_headList->setCurrentItem(item);
}

void EditMode::pasteFromClipboard(QLCPhysical clipboard)
{
    m_phyEdit->pasteFromClipboard(clipboard);
}

void EditMode::slotPhysicalModeChanged()
{
    m_phyEdit->setEnabled(m_globalPhyCheck->isChecked() ? false : true);
    if (m_globalPhyCheck->isChecked())
        m_mode->resetPhysical();
    else
        m_mode->setPhysical(m_phyEdit->physical());
}

/*****************************************************************************
 * Accept
 *****************************************************************************/

void EditMode::accept()
{
    m_mode->setName(m_modeNameEdit->text());
    if (m_overridePhyCheck->isChecked())
        m_mode->setPhysical(m_phyEdit->physical());

    QDialog::accept();
}
<commit_msg>fixture editor: improve "acts on" update<commit_after>/*
  Q Light Controller - Fixture Editor
  editmode.cpp

  Copyright (C) Heikki Junnila

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include <QTreeWidgetItem>
#include <QInputDialog>
#include <QHeaderView>
#include <QMessageBox>
#include <QTreeWidget>
#include <QPushButton>
#include <QComboBox>
#include <QLineEdit>
#include <QSettings>
#include <QSpinBox>
#include <QPoint>
#include <QDebug>
#include <QSize>
#include <QAction>

#include "addchannelsdialog.h"
#include "qlcfixturemode.h"
#include "qlcfixturehead.h"
#include "qlcfixturedef.h"
#include "qlcphysical.h"
#include "qlcchannel.h"

#include "editphysical.h"
#include "editmode.h"
#include "edithead.h"
#include "util.h"
#include "app.h"

#define KSettingsGeometry "editmode/geometry"

#define PROP_PTR Qt::UserRole
#define COL_NUM  0
#define COL_NAME 1
#define COL_ACTS_ON 2

EditMode::EditMode(QWidget *parent, QLCFixtureMode *mode)
    : QDialog(parent)
    , m_mode(new QLCFixtureMode(mode->fixtureDef(), mode))
{
    Q_ASSERT(mode != NULL);
    setupUi(this);
    init();
}

EditMode::EditMode(QWidget *parent, QLCFixtureDef *fixtureDef)
    : QDialog(parent)
    , m_mode(new QLCFixtureMode(fixtureDef))
{
    Q_ASSERT(fixtureDef != NULL);
    setupUi(this);
    init();
}

EditMode::~EditMode()
{
    QSettings settings;
    settings.setValue(KSettingsGeometry, saveGeometry());

    delete m_mode;
}

void EditMode::init()
{
    /* Channels page */
    connect(m_addChannelButton, SIGNAL(clicked()), this, SLOT(slotAddChannelClicked()));
    connect(m_removeChannelButton, SIGNAL(clicked()), this, SLOT(slotRemoveChannelClicked()));
    connect(m_raiseChannelButton, SIGNAL(clicked()), this, SLOT(slotRaiseChannelClicked()));
    connect(m_lowerChannelButton, SIGNAL(clicked()), this, SLOT(slotLowerChannelClicked()));

    m_modeNameEdit->setText(m_mode->name());
    m_modeNameEdit->setValidator(CAPS_VALIDATOR(this));
    refreshChannelList();

    /* Heads page */
    connect(m_addHeadButton, SIGNAL(clicked()), this, SLOT(slotAddHeadClicked()));
    connect(m_removeHeadButton, SIGNAL(clicked()), this, SLOT(slotRemoveHeadClicked()));
    connect(m_editHeadButton, SIGNAL(clicked()), this, SLOT(slotEditHeadClicked()));
    connect(m_raiseHeadButton, SIGNAL(clicked()), this, SLOT(slotRaiseHeadClicked()));
    connect(m_lowerHeadButton, SIGNAL(clicked()), this, SLOT(slotLowerHeadClicked()));

    refreshHeadList();

    /* Physical page */
    m_phyEdit = new EditPhysical(m_mode->physical(), this);
    m_phyEdit->show();
    physicalLayout->addWidget(m_phyEdit);

    if (m_mode->useGlobalPhysical() == false)
        m_overridePhyCheck->setChecked(true);
    slotPhysicalModeChanged();

    connect(m_globalPhyCheck, SIGNAL(clicked(bool)), this, SLOT(slotPhysicalModeChanged()));
    connect(m_overridePhyCheck, SIGNAL(clicked(bool)), this, SLOT(slotPhysicalModeChanged()));
    /* Forward copy/paste requests up to reach the main FixtureEditor clipboard */
    connect(m_phyEdit, SIGNAL(copyToClipboard(QLCPhysical)), this, SIGNAL(copyToClipboard(QLCPhysical)));
    connect(m_phyEdit, SIGNAL(requestPasteFromClipboard()), this, SIGNAL(requestPasteFromClipboard()));

    // Close shortcut
    QAction *action = new QAction(this);
    action->setShortcut(QKeySequence(QKeySequence::Close));
    connect(action, SIGNAL(triggered(bool)), this, SLOT(reject()));
    addAction(action);

    // Geometry
    QSettings settings;
    QVariant var = settings.value(KSettingsGeometry);
    if (var.isValid() == true)
        restoreGeometry(var.toByteArray());
}

QLCFixtureMode *EditMode::mode()
{
    return m_mode;
}

/****************************************************************************
 * Channels page
 ****************************************************************************/

void EditMode::slotAddChannelClicked()
{
    AddChannelsDialog ach(m_mode->fixtureDef()->channels(), m_mode->channels());
    if (ach.exec() != QDialog::Accepted)
        return;

    QList<QLCChannel *> newChannelList = ach.getModeChannelsList();

    // clear the previous list
    m_mode->removeAllChannels();

    // Append the channels
    foreach (QLCChannel *ch, newChannelList)
        m_mode->insertChannel(ch, m_mode->channels().size());

    // Easier to refresh the whole list
    refreshChannelList();
}

void EditMode::slotRemoveChannelClicked()
{
    QLCChannel *ch = currentChannel();

    if (ch != NULL)
    {
        QTreeWidgetItem *item;
        QString select;

        // Pick the item above or below to be selected next
        item = m_channelList->itemAbove(m_channelList->currentItem());
        if (item == NULL)
            item = m_channelList->itemBelow(m_channelList->currentItem());
        if (item != NULL)
            select = item->text(COL_NAME);

        // Remove the channel and the listview item
        m_mode->removeChannel(ch);
        delete m_channelList->currentItem();

        // Easier to refresh the whole list than to decrement all
        // channel numbers after the inserted item
        refreshChannelList();

        // Select another channel
        selectChannel(select);
    }
}

void EditMode::slotRaiseChannelClicked()
{
    QLCChannel *ch = currentChannel();
    int index = 0;

    if (ch == NULL)
        return;

    index = m_mode->channelNumber(ch) - 1;

    // Don't move beyond the beginning of the list
    if (index < 0)
        return;

    m_mode->removeChannel(ch);
    m_mode->insertChannel(ch, index);

    refreshChannelList();
    selectChannel(ch->name());
}

void EditMode::slotLowerChannelClicked()
{
    QLCChannel *ch = currentChannel();
    int index = 0;

    if (ch == NULL)
        return;

    index = m_mode->channelNumber(ch) + 1;

    // Don't move beyond the end of the list
    if (index >= m_mode->channels().size())
        return;

    m_mode->removeChannel(ch);
    m_mode->insertChannel(ch, index);

    refreshChannelList();
    selectChannel(ch->name());
}

void EditMode::slotActsOnChannelChanged(QLCChannel *newActsOnChannel)
{
    QLCChannel *channel = currentChannel();

    if (channel == NULL)
        return;

    m_mode->updateActsOnChannel(channel, newActsOnChannel);
    //refreshChannelList();
}

void EditMode::refreshChannelList()
{
    m_channelList->clear();

    for (int i = 0; i < m_mode->channels().size(); i++)
    {
        QTreeWidgetItem *item = new QTreeWidgetItem(m_channelList);
        QLCChannel *ch = m_mode->channel(i);

        int actsOnChannelIndex = m_mode->channels().indexOf(m_mode->actsOnChannelsList().value(ch));

        Q_ASSERT(ch != NULL);

        QString str;
        item->setText(COL_NUM, str.asprintf("%.3d", (i + 1)));
        item->setText(COL_NAME, ch->name());
        item->setIcon(COL_NAME, ch->getIcon());
        item->setData(COL_NAME, PROP_PTR, (qulonglong) ch);

        QStringList comboList;

        comboList << "-";

        for (int index = 0; index < m_mode->channels().size(); index++)
        {
            QLCChannel *currentChannel = m_mode->channels().at(index);
            comboList << QString::number(index + 1) + " - " + currentChannel->name();
        }

        QComboBox *comboBox = new QComboBox(this);
        comboBox->addItems(comboList);

        if (actsOnChannelIndex >= 0)
            comboBox->setCurrentIndex(actsOnChannelIndex + 1);
        else
            comboBox->setCurrentIndex(0);

        m_channelList->setItemWidget(item, COL_ACTS_ON, comboBox);

        connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setActsOnChannel(int)));
    }
    m_channelList->header()->resizeSections(QHeaderView::ResizeToContents);
}

QLCChannel* EditMode::currentChannel()
{
    QTreeWidgetItem *item;
    QLCChannel *ch = NULL;

    // Convert the string-form ulong to a QLCChannel pointer and return it
    item = m_channelList->currentItem();
    if (item != NULL)
        ch = (QLCChannel*)item->data(COL_NAME, PROP_PTR).toULongLong();

    return ch;
}

void EditMode::selectChannel(const QString &name)
{
    QTreeWidgetItemIterator it(m_channelList);
    while (*it != NULL)
    {
        if ((*it)->text(COL_NAME) == name)
        {
            m_channelList->setCurrentItem((*it));
            break;
        }

        ++it;
    }
}

void EditMode::setActsOnChannel(int index)
{
    int channelNumber = index - 1;

    QLCChannel *actsOnChannel = NULL;

    if (channelNumber >= 0)
        actsOnChannel = m_mode->channels().at(channelNumber);

    slotActsOnChannelChanged(actsOnChannel);
}

/****************************************************************************
 * Heads page
 ****************************************************************************/

void EditMode::slotAddHeadClicked()
{
    EditHead eh(this, QLCFixtureHead(), m_mode);
    if (eh.exec() == QDialog::Accepted)
    {
        m_mode->insertHead(-1, eh.head());
        refreshHeadList();
    }
}

void EditMode::slotRemoveHeadClicked()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return;

    int index = m_headList->indexOfTopLevelItem(item);
    m_mode->removeHead(index);
    refreshHeadList();
}

void EditMode::slotEditHeadClicked()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return;

    EditHead eh(this, currentHead(), m_mode);
    if (eh.exec() == QDialog::Accepted)
    {
        int index = m_headList->indexOfTopLevelItem(item);
        m_mode->replaceHead(index, eh.head());
        refreshHeadList();
    }
}

void EditMode::slotRaiseHeadClicked()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return;

    int index = m_headList->indexOfTopLevelItem(item);

    // Don't move beyond the beginning of the list
    if ((index - 1) < 0)
        return;

    QLCFixtureHead head = currentHead();
    m_mode->removeHead(index);
    m_mode->insertHead(index - 1, head);

    refreshHeadList();
    selectHead(index - 1);
}

void EditMode::slotLowerHeadClicked()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return;

    int index = m_headList->indexOfTopLevelItem(item);

    // Don't move beyond the end of the list
    if ((index + 1) >= m_mode->heads().size())
        return;

    QLCFixtureHead head = currentHead();
    m_mode->removeHead(index);
    m_mode->insertHead(index + 1, head);

    refreshHeadList();
    selectHead(index + 1);
}

void EditMode::refreshHeadList()
{
    m_headList->clear();

    for (int i = 0; i < m_mode->heads().size(); i++)
    {
        QTreeWidgetItem *item = new QTreeWidgetItem(m_headList);
        QLCFixtureHead head = m_mode->heads().at(i);
        QList <quint32> channels(head.channels());
        QString summary;

        std::sort(channels.begin(), channels.end());

        QListIterator <quint32> it(channels);
        while (it.hasNext() == true)
        {
            quint32 chnum = it.next();
            const QLCChannel *ch = m_mode->channel(chnum);
            QTreeWidgetItem *chitem = new QTreeWidgetItem(item);
            if (ch != NULL)
                chitem->setText(0, QString("%1: %2").arg(chnum + 1).arg(ch->name()));
            else
                chitem->setText(0, QString("%1: INVALID!"));
            chitem->setFlags(Qt::NoItemFlags); // Disable channel selection inside heads

            summary += QString::number(chnum + 1);
            if (it.hasNext() == true)
                summary += QString(", ");
        }

        item->setText(0, QString("Head %1 (%2)").arg(i + 1).arg(summary));
    }
    m_headList->resizeColumnToContents(0);
}

QLCFixtureHead EditMode::currentHead()
{
    QTreeWidgetItem *item = m_headList->currentItem();
    if (item == NULL)
        return QLCFixtureHead();

    int index = m_headList->indexOfTopLevelItem(item);
    return m_mode->heads().at(index);
}

void EditMode::selectHead(int index)
{
    if (index >= m_headList->topLevelItemCount())
        return;

    QTreeWidgetItem *item = m_headList->topLevelItem(index);
    m_headList->setCurrentItem(item);
}

void EditMode::pasteFromClipboard(QLCPhysical clipboard)
{
    m_phyEdit->pasteFromClipboard(clipboard);
}

void EditMode::slotPhysicalModeChanged()
{
    m_phyEdit->setEnabled(m_globalPhyCheck->isChecked() ? false : true);
    if (m_globalPhyCheck->isChecked())
        m_mode->resetPhysical();
    else
        m_mode->setPhysical(m_phyEdit->physical());
}

/*****************************************************************************
 * Accept
 *****************************************************************************/

void EditMode::accept()
{
    m_mode->setName(m_modeNameEdit->text());
    if (m_overridePhyCheck->isChecked())
        m_mode->setPhysical(m_phyEdit->physical());

    QDialog::accept();
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/trajectory/CTrajectoryTask.cpp,v $
   $Revision: 1.46 $
   $Name:  $
   $Author: ssahle $
   $Date: 2005/02/27 20:32:53 $
   End CVS Header */

/**
 * CTrajectoryTask class.
 *
 * This class implements a trajectory task which is comprised of a
 * of a problem and a method. Additionally calls to the reporting
 * methods are done when initialized.
 *
 * Created for Copasi by Stefan Hoops 2002
 */

#include <string>

#include "copasi.h"

#include "CTrajectoryTask.h"
#include "CTrajectoryProblem.h"
#include "CTrajectoryMethod.h"
#include "model/CModel.h"
#include "model/CState.h"
#include "report/CKeyFactory.h"
#include "report/CReport.h"
#include "utilities/COutputHandler.h"

#define XXXX_Reporting

CTrajectoryTask::CTrajectoryTask(const CCopasiContainer * pParent):
    CCopasiTask(CCopasiTask::timeCourse, pParent),
    mpState(NULL),
    mTimeSeriesRequested(true),
    mDoOutput(OUTPUT_COMPLETE)
{
  mpProblem = new CTrajectoryProblem(this);
  mpMethod =
    CTrajectoryMethod::createTrajectoryMethod(CCopasiMethod::deterministic,
        (CTrajectoryProblem *) mpProblem);
  this->add(mpMethod, true);
  //mpMethod->setObjectParent(this);
}

/*CTrajectoryTask::CTrajectoryTask(const CTrajectoryTask & src,
                                 const CCopasiContainer * pParent):
    CCopasiTask(src, pParent),
    mpState(src.mpState),
    mTimeSeriesRequested(src.mTimeSeriesRequested)
{fatalError();}*/

CTrajectoryTask::~CTrajectoryTask()
{
  cleanup();
}

void CTrajectoryTask::cleanup()
{
  pdelete(mpState);
}

void CTrajectoryTask::load(CReadConfig & configBuffer)
{
  configBuffer.getVariable("Dynamics", "bool", &mScheduled,
                           CReadConfig::LOOP);

  pdelete(mpProblem);
  mpProblem = new CTrajectoryProblem(this);
  ((CTrajectoryProblem *) mpProblem)->load(configBuffer);

  pdelete(mpMethod);
  mpMethod = CTrajectoryMethod::createTrajectoryMethod();
  this->add(mpMethod, true);
  //mpMethod->setObjectParent(this);
  ((CTrajectoryMethod *)mpMethod)->setProblem((CTrajectoryProblem *) mpProblem);
}

bool CTrajectoryTask::initialize(std::ostream * pOstream)
{
  assert(mpProblem && mpMethod);

  CTrajectoryProblem* pProblem =
    dynamic_cast<CTrajectoryProblem *>(mpProblem);
  assert(pProblem);

  bool success = true;

  if (!mReport.open(pOstream)) success = false;
  if (!mReport.compile()) success = false;
  if (!pProblem->getModel()->compileIfNecessary()) success = false;
  //  if (!pProblem->
  //      setInitialState(pProblem->getModel()->getInitialState()))
  //    success = false;

  //pProblem->setInitialState(pProblem->getModel()->getInitialState());

  return success;
}

bool CTrajectoryTask::process()
{
  assert(mpProblem && mpMethod);

  CTrajectoryProblem * pProblem = (CTrajectoryProblem *) mpProblem;
  CTrajectoryMethod * pMethod = (CTrajectoryMethod *) mpMethod;

  mTimeSeriesRequested = pProblem->timeSeriesRequested();

  pdelete(mpState);
  mpState = new CState(pProblem->getInitialState());

  pMethod->setCurrentState(mpState);
  pMethod->setProblem(pProblem);

  C_FLOAT64 StepSize = pProblem->getStepSize();
  C_FLOAT64 ActualStepSize;
  const C_FLOAT64 & Time = mpState->getTime();
  C_FLOAT64 EndTime = pProblem->getEndTime() - StepSize;
  C_FLOAT64 outputStartTime = pProblem->getOutputStartTime();

  bool flagStopped = false;
  C_FLOAT64 handlerFactor = 1000 / (pProblem->getEndTime() - pProblem->getStartTime());
  if (mpProgressHandler) mpProgressHandler->init(1000, "performing simulation...", true);

  if (mDoOutput)
    {
      pProblem->getModel()->setState(mpState);
      pProblem->getModel()->updateRates();
    }

  if (mDoOutput == OUTPUT_COMPLETE)
    {
      pProblem->getModel()->setState(mpState);
      pProblem->getModel()->updateRates();
      mReport.printHeader();
      if (mpOutputHandler) mpOutputHandler->init();
      if (mTimeSeriesRequested) mTimeSeries.init(pProblem->getStepNumber(), mpState);
    }

  if ((outputStartTime <= Time) && (mDoOutput))
    {
      mReport.printBody();
      if (mpOutputHandler) mpOutputHandler->doOutput();
      if (mTimeSeriesRequested) mTimeSeries.add();
    }

  ActualStepSize = pMethod->step(StepSize, mpState);

  if (mpProgressHandler) flagStopped = mpProgressHandler->progress((C_INT32)((Time - pProblem->getStartTime()) * handlerFactor));

  if ((outputStartTime <= Time) && (mDoOutput))
    {
      pProblem->getModel()->setState(mpState);
      pProblem->getModel()->updateRates();
      mReport.printBody();
      if (mpOutputHandler) mpOutputHandler->doOutput();
      if (mTimeSeriesRequested) mTimeSeries.add();
    }

#ifdef  XXXX_Event
  if (ActualStepSize != StepSize)
    {
      /* Here we will do conditional event processing */
    }
#endif // XXXX_Event

  while ((Time < EndTime) && (!flagStopped))
    {
      ActualStepSize = pMethod->step(StepSize);

      if (mpProgressHandler) flagStopped = mpProgressHandler->progress((C_INT32)((Time - pProblem->getStartTime()) * handlerFactor));

      if ((outputStartTime <= Time) && (mDoOutput))
        {
          pProblem->getModel()->setState(mpState);
          pProblem->getModel()->updateRates();
          mReport.printBody();
          if (mpOutputHandler) mpOutputHandler->doOutput();
          if (mTimeSeriesRequested) mTimeSeries.add();
        }
#ifdef  XXXX_Event
      if (ActualStepSize != StepSize)
        {
          /* Here we will do conditional event processing */
        }
#endif // XXXX_Event
    }

  while ((Time < pProblem->getEndTime()) && (!flagStopped))
    {
      ActualStepSize = pMethod->step(pProblem->getEndTime() - Time);

      if (mpProgressHandler) flagStopped = mpProgressHandler->progress((C_INT32)((Time - pProblem->getStartTime()) * handlerFactor));

      if ((outputStartTime <= Time) && (mDoOutput))
        {
          pProblem->getModel()->setState(mpState);
          pProblem->getModel()->updateRates();
          mReport.printBody();
          if (mpOutputHandler) mpOutputHandler->doOutput();
          if (mTimeSeriesRequested) mTimeSeries.add();
        }
#ifdef  XXXX_Event
      if (ActualStepSize != (pProblem->getEndTime() - Time))
        {
          /* Here we will do conditional event processing */
        }
#endif // XXXX_Event
    }

  //pProblem->setEndState(new CState(*mpState));

  if (mpProgressHandler) mpProgressHandler->finish();
  pProblem->getModel()->setState(mpState);
  pProblem->getModel()->updateRates();

  if ((outputStartTime <= Time) && (mDoOutput))
    {
      mReport.printFooter();
      if (mpOutputHandler) mpOutputHandler->finish();
      if (mTimeSeriesRequested) mTimeSeries.finish();
    }

  return true;
}

//virtual
bool CTrajectoryTask::processForScan(bool useInitialConditions, bool doOutput)
{
  assert(mpProblem /*&& mpMethod*/);

  CTrajectoryProblem* pProblem =
    dynamic_cast<CTrajectoryProblem *>(mpProblem);
  assert(pProblem);

  //set flag for output
  OutputFlag storeOutput = mDoOutput;
  if (doOutput)
    mDoOutput = OUTPUT;
  else
    mDoOutput = NO_OUTPUT;

  //handle initial conditions
  CState storeState;
  if (!useInitialConditions)
    {
      storeState = pProblem->getInitialState();
      pProblem->getModel()->setTime(pProblem->getInitialState().getTime());
      pProblem->setInitialState(pProblem->getModel()->getState());
      // pProblem->getInitialState().setTime(storeState.getTime());
    }

  //switch off time series storage
  bool storeTS = pProblem->timeSeriesRequested();
  pProblem->setTimeSeriesRequested(false);

  //do the calculation
  process();

  //restore ...
  if (!useInitialConditions) pProblem->setInitialState(storeState);
  mDoOutput = storeOutput;
  pProblem->setTimeSeriesRequested(storeTS);

  return true;
}

bool CTrajectoryTask::processSimple(bool singleStep) //without output
{
  assert(mpProblem && mpMethod);

  CTrajectoryProblem * pProblem = (CTrajectoryProblem *) mpProblem;
  CTrajectoryMethod * pMethod = (CTrajectoryMethod *) mpMethod;

  //give the method a state to work on
  pdelete(mpState);
  mpState = new CState(pProblem->getInitialState());
  pMethod->setCurrentState(mpState);

  pMethod->setProblem(pProblem);

  bool flagStopped = false;
  C_FLOAT64 handlerFactor = 1000 / (pProblem->getEndTime() - pProblem->getStartTime());
  if (mpProgressHandler) mpProgressHandler->init(1000, "performing simulation...", true);

  //first step
  C_FLOAT64 StepSize = pProblem->getEndTime() - pProblem->getInitialState().getTime();
  pMethod->step(StepSize, &pProblem->getInitialState());

  if (mpProgressHandler) flagStopped =
      mpProgressHandler->progress((C_INT32)((mpState->getTime() - pProblem->getStartTime()) * handlerFactor));

  if (mpState->getTime() == pProblem->getEndTime()) return true; //end reached in one step
  if (singleStep) return false; //end not reached but only one step requested

  //more Steps if necessary
  while ((mpState->getTime() < pProblem->getEndTime()) && (!flagStopped))
    {
      StepSize = pProblem->getEndTime() - mpState->getTime();
      pMethod->step(StepSize);

      if (mpProgressHandler) flagStopped =
          mpProgressHandler->progress((C_INT32)((mpState->getTime() - pProblem->getStartTime()) * handlerFactor));
    }

  //pProblem->setEndState(new CState(*mpState));

  //if (mpProgressHandler) mpProgressHandler->finish();

  return true;
}

bool CTrajectoryTask::setMethodType(const int & type)
{
  CCopasiMethod::SubType Type = (CCopasiMethod::SubType) type;

  if (!CTrajectoryMethod::isValidSubType(Type)) return false;
  if (mpMethod->getSubType() == Type) return true;

  pdelete (mpMethod);
  mpMethod =
    CTrajectoryMethod::createTrajectoryMethod(Type,
        (CTrajectoryProblem *) mpProblem);
  this->add(mpMethod, true);
  //mpMethod->setObjectParent(this);

  return true;
}

CState * CTrajectoryTask::getState()
{return mpState;}

const CTimeSeries & CTrajectoryTask::getTimeSeries() const
  {return mTimeSeries;}
<commit_msg>Enabled support for backward integration.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/trajectory/CTrajectoryTask.cpp,v $
   $Revision: 1.47 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/04/14 15:50:20 $
   End CVS Header */

/**
 * CTrajectoryTask class.
 *
 * This class implements a trajectory task which is comprised of a
 * of a problem and a method. Additionally calls to the reporting
 * methods are done when initialized.
 *
 * Created for Copasi by Stefan Hoops 2002
 */

#include <string>

#include "copasi.h"

#include "CTrajectoryTask.h"
#include "CTrajectoryProblem.h"
#include "CTrajectoryMethod.h"
#include "model/CModel.h"
#include "model/CState.h"
#include "report/CKeyFactory.h"
#include "report/CReport.h"
#include "utilities/COutputHandler.h"

#define XXXX_Reporting

bool fle(const C_FLOAT64 & d1, const C_FLOAT64 & d2)
{return (d1 <= d2);}

bool fl(const C_FLOAT64 & d1, const C_FLOAT64 & d2)
{return (d1 < d2);}

bool ble(const C_FLOAT64 & d1, const C_FLOAT64 & d2)
{return (d1 >= d2);}

bool bl(const C_FLOAT64 & d1, const C_FLOAT64 & d2)
{return (d1 > d2);}

CTrajectoryTask::CTrajectoryTask(const CCopasiContainer * pParent):
    CCopasiTask(CCopasiTask::timeCourse, pParent),
    mpState(NULL),
    mTimeSeriesRequested(true),
    mDoOutput(OUTPUT_COMPLETE)
{
  mpProblem = new CTrajectoryProblem(this);
  mpMethod =
    CTrajectoryMethod::createTrajectoryMethod(CCopasiMethod::deterministic,
        (CTrajectoryProblem *) mpProblem);
  this->add(mpMethod, true);
  //mpMethod->setObjectParent(this);
}

/*CTrajectoryTask::CTrajectoryTask(const CTrajectoryTask & src,
                                 const CCopasiContainer * pParent):
    CCopasiTask(src, pParent),
    mpState(src.mpState),
    mTimeSeriesRequested(src.mTimeSeriesRequested)
{fatalError();}*/

CTrajectoryTask::~CTrajectoryTask()
{
  cleanup();
}

void CTrajectoryTask::cleanup()
{
  pdelete(mpState);
}

void CTrajectoryTask::load(CReadConfig & configBuffer)
{
  configBuffer.getVariable("Dynamics", "bool", &mScheduled,
                           CReadConfig::LOOP);

  pdelete(mpProblem);
  mpProblem = new CTrajectoryProblem(this);
  ((CTrajectoryProblem *) mpProblem)->load(configBuffer);

  pdelete(mpMethod);
  mpMethod = CTrajectoryMethod::createTrajectoryMethod();
  this->add(mpMethod, true);
  //mpMethod->setObjectParent(this);
  ((CTrajectoryMethod *)mpMethod)->setProblem((CTrajectoryProblem *) mpProblem);
}

bool CTrajectoryTask::initialize(std::ostream * pOstream)
{
  assert(mpProblem && mpMethod);

  CTrajectoryProblem* pProblem =
    dynamic_cast<CTrajectoryProblem *>(mpProblem);
  assert(pProblem);

  bool success = true;

  if (!mReport.open(pOstream)) success = false;
  if (!mReport.compile()) success = false;
  if (!pProblem->getModel()->compileIfNecessary()) success = false;
  //  if (!pProblem->
  //      setInitialState(pProblem->getModel()->getInitialState()))
  //    success = false;

  //pProblem->setInitialState(pProblem->getModel()->getInitialState());

  return success;
}

bool CTrajectoryTask::process()
{
  assert(mpProblem && mpMethod);

  CTrajectoryProblem * pProblem = (CTrajectoryProblem *) mpProblem;
  CTrajectoryMethod * pMethod = (CTrajectoryMethod *) mpMethod;

  mTimeSeriesRequested = pProblem->timeSeriesRequested();

  pdelete(mpState);
  mpState = new CState(pProblem->getInitialState());

  pMethod->setCurrentState(mpState);
  pMethod->setProblem(pProblem);

  C_FLOAT64 StepSize = pProblem->getStepSize();

  bool (*LE)(const C_FLOAT64 &, const C_FLOAT64 &);
  bool (*L)(const C_FLOAT64 &, const C_FLOAT64 &);
  if (StepSize < 0.0)
    {
      LE = &ble;
      L = &bl;
    }
  else
    {
      LE = &fle;
      L = &fl;
    }

  C_FLOAT64 ActualStepSize;
  const C_FLOAT64 & Time = mpState->getTime();
  C_FLOAT64 EndTime = pProblem->getEndTime() - StepSize;
  C_FLOAT64 outputStartTime = pProblem->getOutputStartTime();

  if (StepSize == 0.0 && pProblem->getEndTime() != pProblem->getStartTime())
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCTrajectoryMethod + 5, StepSize);
      return false;
    }
  bool flagStopped = false;
  C_FLOAT64 handlerFactor = 1000 / (pProblem->getEndTime() - pProblem->getStartTime());
  if (mpProgressHandler) mpProgressHandler->init(1000, "performing simulation...", true);

  if (mDoOutput)
    {
      pProblem->getModel()->setState(mpState);
      pProblem->getModel()->updateRates();
    }

  if (mDoOutput == OUTPUT_COMPLETE)
    {
      pProblem->getModel()->setState(mpState);
      pProblem->getModel()->updateRates();
      mReport.printHeader();
      if (mpOutputHandler) mpOutputHandler->init();
      if (mTimeSeriesRequested) mTimeSeries.init(pProblem->getStepNumber(), mpState);
    }

  if ((*LE)(outputStartTime, Time) && (mDoOutput))
    {
      mReport.printBody();
      if (mpOutputHandler) mpOutputHandler->doOutput();
      if (mTimeSeriesRequested) mTimeSeries.add();
    }

  ActualStepSize = pMethod->step(StepSize, mpState);

  if (mpProgressHandler) flagStopped =
      mpProgressHandler->progress((C_INT32)((Time - pProblem->getStartTime()) * handlerFactor));

  if ((*LE)(outputStartTime, Time) && (mDoOutput))
    {
      pProblem->getModel()->setState(mpState);
      pProblem->getModel()->updateRates();
      mReport.printBody();
      if (mpOutputHandler) mpOutputHandler->doOutput();
      if (mTimeSeriesRequested) mTimeSeries.add();
    }

#ifdef  XXXX_Event
  if (ActualStepSize != StepSize)
    {
      /* Here we will do conditional event processing */
    }
#endif // XXXX_Event

  while ((*L)(Time, EndTime) && (!flagStopped))
    {
      ActualStepSize = pMethod->step(StepSize);

      if (mpProgressHandler) flagStopped = mpProgressHandler->progress((C_INT32)((Time - pProblem->getStartTime()) * handlerFactor));

      if ((*LE)(outputStartTime, Time) && (mDoOutput))
        {
          pProblem->getModel()->setState(mpState);
          pProblem->getModel()->updateRates();
          mReport.printBody();
          if (mpOutputHandler) mpOutputHandler->doOutput();
          if (mTimeSeriesRequested) mTimeSeries.add();
        }
#ifdef  XXXX_Event
      if (ActualStepSize != StepSize)
        {
          /* Here we will do conditional event processing */
        }
#endif // XXXX_Event
    }

  while ((*L)(Time, pProblem->getEndTime()) && (!flagStopped))
    {
      ActualStepSize = pMethod->step(pProblem->getEndTime() - Time);

      if (mpProgressHandler) flagStopped = mpProgressHandler->progress((C_INT32)((Time - pProblem->getStartTime()) * handlerFactor));

      if ((*LE)(outputStartTime, Time) && (mDoOutput))
        {
          pProblem->getModel()->setState(mpState);
          pProblem->getModel()->updateRates();
          mReport.printBody();
          if (mpOutputHandler) mpOutputHandler->doOutput();
          if (mTimeSeriesRequested) mTimeSeries.add();
        }
#ifdef  XXXX_Event
      if (ActualStepSize != (pProblem->getEndTime() - Time))
        {
          /* Here we will do conditional event processing */
        }
#endif // XXXX_Event
    }

  //pProblem->setEndState(new CState(*mpState));

  if (mpProgressHandler) mpProgressHandler->finish();
  pProblem->getModel()->setState(mpState);
  pProblem->getModel()->updateRates();

  if ((*LE)(outputStartTime, Time) && (mDoOutput))
    {
      mReport.printFooter();
      if (mpOutputHandler) mpOutputHandler->finish();
      if (mTimeSeriesRequested) mTimeSeries.finish();
    }

  return true;
}

//virtual
bool CTrajectoryTask::processForScan(bool useInitialConditions, bool doOutput)
{
  assert(mpProblem /*&& mpMethod*/);

  CTrajectoryProblem* pProblem =
    dynamic_cast<CTrajectoryProblem *>(mpProblem);
  assert(pProblem);

  //set flag for output
  OutputFlag storeOutput = mDoOutput;
  if (doOutput)
    mDoOutput = OUTPUT;
  else
    mDoOutput = NO_OUTPUT;

  //handle initial conditions
  CState storeState;
  if (!useInitialConditions)
    {
      storeState = pProblem->getInitialState();
      pProblem->getModel()->setTime(pProblem->getInitialState().getTime());
      pProblem->setInitialState(pProblem->getModel()->getState());
      // pProblem->getInitialState().setTime(storeState.getTime());
    }

  //switch off time series storage
  bool storeTS = pProblem->timeSeriesRequested();
  pProblem->setTimeSeriesRequested(false);

  //do the calculation
  process();

  //restore ...
  if (!useInitialConditions) pProblem->setInitialState(storeState);
  mDoOutput = storeOutput;
  pProblem->setTimeSeriesRequested(storeTS);

  return true;
}

bool CTrajectoryTask::processSimple(bool singleStep) //without output
{
  assert(mpProblem && mpMethod);

  CTrajectoryProblem * pProblem = (CTrajectoryProblem *) mpProblem;
  CTrajectoryMethod * pMethod = (CTrajectoryMethod *) mpMethod;

  //give the method a state to work on
  pdelete(mpState);
  mpState = new CState(pProblem->getInitialState());
  pMethod->setCurrentState(mpState);

  pMethod->setProblem(pProblem);

  C_FLOAT64 StepSize = pProblem->getEndTime() - pProblem->getInitialState().getTime();
  bool (*L)(const C_FLOAT64 &, const C_FLOAT64 &) = (StepSize < 0.0) ? &bl : &fl;

  bool flagStopped = false;
  C_FLOAT64 handlerFactor = 1000 / (pProblem->getEndTime() - pProblem->getStartTime());
  if (mpProgressHandler) mpProgressHandler->init(1000, "performing simulation...", true);

  //first step
  pMethod->step(StepSize, &pProblem->getInitialState());

  if (mpProgressHandler) flagStopped =
      mpProgressHandler->progress((C_INT32)((mpState->getTime() - pProblem->getStartTime()) * handlerFactor));

  if (mpState->getTime() == pProblem->getEndTime()) return true; //end reached in one step
  if (singleStep) return false; //end not reached but only one step requested

  //more Steps if necessary
  while ((*L)(mpState->getTime(), pProblem->getEndTime()) && (!flagStopped))
    {
      StepSize = pProblem->getEndTime() - mpState->getTime();
      pMethod->step(StepSize);

      if (mpProgressHandler) flagStopped =
          mpProgressHandler->progress((C_INT32)((mpState->getTime() - pProblem->getStartTime()) * handlerFactor));
    }

  //pProblem->setEndState(new CState(*mpState));

  //if (mpProgressHandler) mpProgressHandler->finish();

  return true;
}

bool CTrajectoryTask::setMethodType(const int & type)
{
  CCopasiMethod::SubType Type = (CCopasiMethod::SubType) type;

  if (!CTrajectoryMethod::isValidSubType(Type)) return false;
  if (mpMethod->getSubType() == Type) return true;

  pdelete (mpMethod);
  mpMethod =
    CTrajectoryMethod::createTrajectoryMethod(Type,
        (CTrajectoryProblem *) mpProblem);
  this->add(mpMethod, true);
  //mpMethod->setObjectParent(this);

  return true;
}

CState * CTrajectoryTask::getState()
{return mpState;}

const CTimeSeries & CTrajectoryTask::getTimeSeries() const
  {return mTimeSeries;}
<|endoftext|>


<commit_before>#include <SDL.h>
#include "platform/sdl/audio_postprocess.h"
#include "platform/sdl/renderer.h"
#include "platform/sdl/gui.h"
#include "core/core.h"

int main(int argc, char *argv[])
{
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
	std::string file_name;

	auto rtc_saver = [&](std::chrono::seconds epoch, const u8* data, u32 size)
	{
		std::ofstream to_save(file_name + "_rtc", std::ios::trunc | std::ios::binary);
		to_save << epoch.count();
		to_save.write(reinterpret_cast<const char*>(data), size * sizeof(u8));
	};

	Core emu_core;

	AudioSDL audio_post;
	GuiSDL gui(3*160, 3*144, "GBE");
	RendererSDL renderer(gui.get_display());

	external_callbacks endpoints;

	endpoints.audio_control = make_function(&AudioSDL::dummy, &audio_post);
	endpoints.swap_sample_buffer = make_function(&AudioSDL::swap_buffers, &audio_post);

	emu_core.attach_callbacks(endpoints);
	emu_core.enable_debugger();

	std::unique_ptr<u8[]> rom_mem;
	std::unique_ptr<u8[]> ram_mem;
	u8 rtc_mem[5] = {};

	while (true)
	{
		std::cout << "Insert cartrige path:\n";
		std::cin >> file_name;

		std::ifstream rom(file_name, std::ios::binary);

		if (rom.is_open())
		{
			//load rom
			rom.seekg(0, std::ios_base::end);
			const auto rom_size = rom.tellg();
			rom.seekg(0, std::ios_base::beg);

			rom_mem = std::make_unique<u8[]>(rom_size);
			rom.read(reinterpret_cast<char*>(rom_mem.get()), rom_size);

			//attach rom
			emu_core.load_rom(rom_mem.get(), rom_size);

			//if cartrige has ram, create it
			const u32 ram_size = emu_core.get_ram_size();

			if (ram_size > 0)
			{
				ram_mem = std::make_unique<u8[]>(ram_size);

				if (emu_core.has_battery_ram())
				{
					std::ifstream ram(file_name + "_ram", std::ios::binary);

					if (ram.is_open())
						ram.read(reinterpret_cast<char*>(ram_mem.get()), ram_size);
				}

				emu_core.load_ram(ram_mem.get(), ram_size);
			}

			if (emu_core.has_rtc())
			{
				std::ifstream rtc(file_name + "_rtc", std::ios::binary);

				if (rtc.is_open())
				{
					i64 timestamp = 0;
					rtc >> timestamp;
					rtc.read(reinterpret_cast<char*>(rtc_mem), sizeof(rtc_mem));

					//assumption: it`s UNIX time (until C++20 it`s implementation defined)
					const auto current_time = std::chrono::system_clock::now();
					const auto prev_time = std::chrono::time_point<std::chrono::system_clock>(std::chrono::seconds(timestamp));
					const auto passed_time = std::chrono::duration_cast<std::chrono::seconds>(current_time - prev_time);

					//TODO: create local current_time for MBC
					//TODO: update rtc according to enabled flag & passed seconds since last time
				}

				emu_core.load_rtc(rtc_mem, 5);
			}

			emu_core.setup_core();

			std::string cart_name = emu_core.get_cart_name();
			gui.set_window_title(cart_name);

			std::cout << "Cartrige loaded!\n";
			break;
		}

		std::cout << "Failed to load cartrige!\n";
	}

	emu_core.set_frame_buffer(renderer.draw_frame());

	while (gui.is_running())
	{
		gui.pump_input(emu_core);
		emu_core.run_one_frame();
		emu_core.set_frame_buffer(renderer.draw_frame());
	}

	//save ram if it has battery
	if (emu_core.has_battery_ram())
	{
		const u32 ram_size = emu_core.get_ram_size();
		std::ofstream to_save(file_name + "_ram", std::ios::trunc | std::ios::binary);
		to_save.write(reinterpret_cast<const char*>(ram_mem.get()), ram_size);
	}

	//save rtc if present
	if (emu_core.has_rtc())
	{
		//TODO: if enabled, make last update using var given to mbc

		const auto new_timestamp = std::chrono::system_clock::now();

		std::ofstream to_save(file_name + "_rtc", std::ios::trunc | std::ios::binary);
		to_save << new_timestamp.time_since_epoch().count();
		to_save.write(reinterpret_cast<const char*>(rtc_mem), sizeof(rtc_mem));
	}

	return 0;
}
<commit_msg>added rtc file time update<commit_after>#include <SDL.h>
#include "platform/sdl/audio_postprocess.h"
#include "platform/sdl/renderer.h"
#include "platform/sdl/gui.h"
#include "core/core.h"

int main(int argc, char *argv[])
{
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
	std::string file_name;

	auto rtc_saver = [&](std::chrono::seconds epoch, const u8* data, u32 size)
	{
		std::ofstream to_save(file_name + "_rtc", std::ios::trunc | std::ios::binary);
		to_save << epoch.count();
		to_save.write(reinterpret_cast<const char*>(data), size * sizeof(u8));
	};

	Core emu_core;

	AudioSDL audio_post;
	GuiSDL gui(3*160, 3*144, "GBE");
	RendererSDL renderer(gui.get_display());

	external_callbacks endpoints;

	endpoints.audio_control = make_function(&AudioSDL::dummy, &audio_post);
	endpoints.swap_sample_buffer = make_function(&AudioSDL::swap_buffers, &audio_post);

	emu_core.attach_callbacks(endpoints);
	emu_core.enable_debugger();

	std::unique_ptr<u8[]> rom_mem;
	std::unique_ptr<u8[]> ram_mem;
	std::array<u8, 5> rtc_mem;

	while (true)
	{
		std::cout << "Insert cartrige path:\n";
		std::cin >> file_name;

		std::ifstream rom(file_name, std::ios::binary);

		if (rom.is_open())
		{
			//load rom
			rom.seekg(0, std::ios_base::end);
			const auto rom_size = rom.tellg();
			rom.seekg(0, std::ios_base::beg);

			rom_mem = std::make_unique<u8[]>(rom_size);
			rom.read(reinterpret_cast<char*>(rom_mem.get()), rom_size);

			//attach rom
			emu_core.load_rom(rom_mem.get(), rom_size);

			//if cartrige has ram, create it
			const u32 ram_size = emu_core.get_ram_size();

			if (ram_size > 0)
			{
				ram_mem = std::make_unique<u8[]>(ram_size);

				if (emu_core.has_battery_ram())
				{
					std::ifstream ram(file_name + "_ram", std::ios::binary);

					if (ram.is_open())
						ram.read(reinterpret_cast<char*>(ram_mem.get()), ram_size);
				}

				emu_core.load_ram(ram_mem.get(), ram_size);
			}

			if (emu_core.has_rtc())
			{
				std::ifstream rtc(file_name + "_rtc", std::ios::binary);

				if (rtc.is_open())
				{
					i64 timestamp = 0;
					rtc >> timestamp;
					rtc.read(reinterpret_cast<char*>(rtc_mem.data()), rtc_mem.size());

					//assumption: it`s UNIX time (until C++20 it`s implementation defined)
					const auto current_time = std::chrono::system_clock::now();
					const auto prev_time = std::chrono::time_point<std::chrono::system_clock>(std::chrono::seconds(timestamp));
					const auto passed_time = std::chrono::duration_cast<std::chrono::seconds>(current_time - prev_time);

					if (check_bit(rtc_mem[5], 6)) //if clock enabled
					{
						auto new_seconds = rtc_mem[0] + passed_time.count();
						auto new_minutes = rtc_mem[1] + new_seconds / 60;
						auto new_hours = rtc_mem[2] + new_minutes / 60;
						auto new_days = (((rtc_mem[4] & 1) << 8) | rtc_mem[3]) + (new_hours / 24);

						rtc_mem[0] = new_seconds % 60;
						rtc_mem[1] = new_minutes % 60;
						rtc_mem[2] = new_hours % 24;
						rtc_mem[3] = (new_days % 512) & 0xFF;
						rtc_mem[4] = change_bit(rtc_mem[4], (new_days % 512) > 255, 0);
						rtc_mem[4] = change_bit(rtc_mem[4], new_days > 511, 7);
					}

					//TODO: create local current_time for MBC
				}

				emu_core.load_rtc(rtc_mem.data(), rtc_mem.size());
			}

			emu_core.setup_core();

			std::string cart_name = emu_core.get_cart_name();
			gui.set_window_title(cart_name);

			std::cout << "Cartrige loaded!\n";
			break;
		}

		std::cout << "Failed to load cartrige!\n";
	}

	emu_core.set_frame_buffer(renderer.draw_frame());

	while (gui.is_running())
	{
		gui.pump_input(emu_core);
		emu_core.run_one_frame();
		emu_core.set_frame_buffer(renderer.draw_frame());
	}

	//save ram if it has battery
	if (emu_core.has_battery_ram())
	{
		const u32 ram_size = emu_core.get_ram_size();
		std::ofstream to_save(file_name + "_ram", std::ios::trunc | std::ios::binary);
		to_save.write(reinterpret_cast<const char*>(ram_mem.get()), ram_size);
	}

	//save rtc if present
	if (emu_core.has_rtc())
	{
		//TODO: if enabled, make last update using var given to mbc

		const auto new_timestamp = std::chrono::system_clock::now();

		std::ofstream to_save(file_name + "_rtc", std::ios::trunc | std::ios::binary);
		to_save << new_timestamp.time_since_epoch().count();
		to_save.write(reinterpret_cast<const char*>(rtc_mem.data()), rtc_mem.size());
	}

	return 0;
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{}

void MainWindow::setIP(QHostAddress myIP, QHostAddress partnerIP)
{
    ui->setupUi(this);

    ui->ErrorLabel->setText("No error :)");

    //Camera and image processer settings
    CaptureCamera.open(0);
    if(CaptureCamera.isOpened() == false)
    {
        ui->ErrorLabel->setText("Camera Error");
        std::cerr<< "Camera open error" <<std::endl;
    }

    CamSize = OriginalImageMat.size();
    Processer = new ImageProcesser(CamSize);
    ProcessTimer = new QTimer(this);
    connect(ProcessTimer, SIGNAL(timeout()), this, SLOT(processVideoAndUpdateQUI()));

    ProcessTimer->start(100); //tested with QElapsedTimer, 50 was too low... it generated runtime between 60-90 msec
                              //with this we have ~12 msec :)

    //Add the graphics to graphicsview
    scene = new QGraphicsScene(0,0,Settings::SCREEN_WIDTH,Settings::SCREEN_HEIGHT,ui->graphicsView);
    ui->graphicsView->setScene(scene);

    //Other initializations
    myRoad = new Road();
    lives = Settings::STARTLIFE;
    ui->MyLifeLCD->display(lives);
    distance = 0;
    QObject::connect(myRoad, SIGNAL(sendLifeNumber(int)), this, SLOT(receiveLifeNumber(int)));
    QObject::connect(myRoad, SIGNAL(sendDistanceNumber(int)), this, SLOT(receiveDistanceNumber(int)));
    QObject::connect(myRoad, SIGNAL(stopGame()), this, SLOT(lose()));
    scene->addItem(myRoad);

    //Start the game
    QObject::connect(&timer, SIGNAL(timeout()), scene, SLOT(advance()));

    MyIpAddr=myIP;
    ui->MyIP->setText("My IP: " + MyIpAddr.toString());
    PartnerIpAddr=partnerIP;
    ui->PartnerIP->setText("Partner IP: " + PartnerIpAddr.toString());
    n = new Network();
    n->setIp(MyIpAddr,PartnerIpAddr);
    n->startBinding();
    QObject::connect(n, SIGNAL(receivedImage(QImage)), this, SLOT(receiveNetworkImage(QImage)));
    gameStarted = false;
    this->show();
}

void MainWindow::receiveLifeNumber(int i)
{
    lives = i;
    if(lives>=0) ui->MyLifeLCD->display(lives);
}

void MainWindow::receiveDistanceNumber(int i)
{
    distance = i;
    ui->MyDistLCD->display(distance);
}

void MainWindow::lose(){
    timer.stop();
    QMessageBox::StandardButton reply;
      reply = QMessageBox::question(this, "Rematch", "Would you like to restart the game?",
                                    QMessageBox::Yes|QMessageBox::No);
      if (reply == QMessageBox::Yes) {
          restart();
      } else {
          closeVideoStream();
          close();
          exit(0);
      }
}

void MainWindow::processVideoAndUpdateQUI()
{
    ProcUpdateElapsedTime.start();
    CaptureCamera.read(OriginalImageMat);

    if (OriginalImageMat.empty()) return;

    cv::resize(OriginalImageMat, ResizedImageMat, cv::Size(352,220), 0, 0, cv::INTER_CUBIC); //resizing the image to fit in the UI
    cv::flip(ResizedImageMat, ResizedImageMat, 1); //eliminating the mirror effect

    //Add the picture to the processer
    int move = Processer->getMove(ResizedImageMat);
    //std::cout << "move: " << move <<std::endl;

    //Move the car
    if(prevmove == 0)
    {
        myRoad->moveCar(move);
    }
    prevmove = move;

    cv::cvtColor(ResizedImageMat, ResizedImageMat, CV_BGR2RGB); //converting the image to RGB
    cv::rectangle(ResizedImageMat,cv::Rect(0, 0, 100, 130),cv::Scalar(200));
    cv::rectangle(ResizedImageMat,cv::Rect(250,0,102,130),cv::Scalar(200));

    QImage OriginalImage((uchar*)ResizedImageMat.data,
                         ResizedImageMat.cols,
                         ResizedImageMat.rows,
                         ResizedImageMat.step,
                         QImage::Format_RGB888); //Creating the QImage for the label
    QImage NetworkSendImage = OriginalImage;
    NetworkSendImage = NetworkSendImage.scaledToHeight(165);

    ui->MyVideoLabel->setPixmap(QPixmap::fromImage(OriginalImage));

    //Sending number of lives and distance embedded in the image
    NetworkSendImage.setText("lives", QString::number(lives));
    NetworkSendImage.setText("distance", QString::number(distance));

    n->sendData(NetworkSendImage); //sending the image over the network

//    std::cerr << "processVideoAndUpdateQUI() elapsed time: " << ProcUpdateElapsedTime.elapsed() << " msec" << std::endl << std::endl;
}

//Public slot that receives the image from the networking thread
void MainWindow::receiveNetworkImage(QImage q)
{
    if (!gameStarted)
    {
        //Start the game
        timer.start(Settings::FREQUENCY);
        gameStarted = true;
    }
    ui->NetworkCamVideo->setPixmap(QPixmap::fromImage(q)); //putting the received image to the gui
    if(q.text("lives").toInt()>=0) ui->NetworkLifeLCD->display(q.text("lives"));
    else lose();
    ui->NetworkDistLCD->display(q.text("distance"));
}

MainWindow::~MainWindow()
{
    delete ui;
    delete ProcessTimer;
    delete Processer;
    delete n;
    delete scene;
    delete myCar;
    delete myRoad;
}

void MainWindow::closeVideoStream()
{
    ProcessTimer->stop();
    //std::cout << "Video process timer stopped" <<std::endl;
    CaptureCamera.release();
    //std::cout << "Camera released" <<std::endl;
}

void MainWindow::restart()
{
        delete(myRoad);
        myRoad = new Road();
        lives = Settings::STARTLIFE;
        ui->MyLifeLCD->display(lives);
        distance = 0;
        ui->MyDistLCD->display(distance);
        scene->addItem(myRoad);
        timer.start(Settings::FREQUENCY);
}

// Kezeli a billentyűlenyomást
void MainWindow::keyPressEvent(QKeyEvent *event){
    switch (event->key())
    {
        case Qt::Key_Right:
                myRoad->moveCar(1); //turn right;
            break;
        case Qt::Key_Left:
                myRoad->moveCar(-1); //turn left;
            break;
        case Qt::Key_Escape:
            closeVideoStream();
            close();
            exit(0);
            break;
        default:
            break;
    }
}
<commit_msg>restart again hotfix #ˇ2<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{}

void MainWindow::setIP(QHostAddress myIP, QHostAddress partnerIP)
{
    ui->setupUi(this);

    ui->ErrorLabel->setText("No error :)");

    //Camera and image processer settings
    CaptureCamera.open(0);
    if(CaptureCamera.isOpened() == false)
    {
        ui->ErrorLabel->setText("Camera Error");
        std::cerr<< "Camera open error" <<std::endl;
    }

    CamSize = OriginalImageMat.size();
    Processer = new ImageProcesser(CamSize);
    ProcessTimer = new QTimer(this);
    connect(ProcessTimer, SIGNAL(timeout()), this, SLOT(processVideoAndUpdateQUI()));

    ProcessTimer->start(100); //tested with QElapsedTimer, 50 was too low... it generated runtime between 60-90 msec
                              //with this we have ~12 msec :)

    //Add the graphics to graphicsview
    scene = new QGraphicsScene(0,0,Settings::SCREEN_WIDTH,Settings::SCREEN_HEIGHT,ui->graphicsView);
    ui->graphicsView->setScene(scene);

    //Other initializations
    myRoad = new Road();
    lives = Settings::STARTLIFE;
    ui->MyLifeLCD->display(lives);
    distance = 0;
    QObject::connect(myRoad, SIGNAL(sendLifeNumber(int)), this, SLOT(receiveLifeNumber(int)));
    QObject::connect(myRoad, SIGNAL(sendDistanceNumber(int)), this, SLOT(receiveDistanceNumber(int)));
    QObject::connect(myRoad, SIGNAL(stopGame()), this, SLOT(lose()));
    scene->addItem(myRoad);

    //Start the game
    QObject::connect(&timer, SIGNAL(timeout()), scene, SLOT(advance()));

    MyIpAddr=myIP;
    ui->MyIP->setText("My IP: " + MyIpAddr.toString());
    PartnerIpAddr=partnerIP;
    ui->PartnerIP->setText("Partner IP: " + PartnerIpAddr.toString());
    n = new Network();
    n->setIp(MyIpAddr,PartnerIpAddr);
    n->startBinding();
    QObject::connect(n, SIGNAL(receivedImage(QImage)), this, SLOT(receiveNetworkImage(QImage)));
    gameStarted = false;
    this->show();
}

void MainWindow::receiveLifeNumber(int i)
{
    lives = i;
    if(lives>=0) ui->MyLifeLCD->display(lives);
}

void MainWindow::receiveDistanceNumber(int i)
{
    distance = i;
    ui->MyDistLCD->display(distance);
}

void MainWindow::lose(){
    timer.stop();
    QMessageBox::StandardButton reply;
      reply = QMessageBox::question(this, "Rematch", "Would you like to restart the game?",
                                    QMessageBox::Yes|QMessageBox::No);
      if (reply == QMessageBox::Yes) {
          restart();
      } else {
          closeVideoStream();
          close();
          exit(0);
      }
}

void MainWindow::processVideoAndUpdateQUI()
{
    ProcUpdateElapsedTime.start();
    CaptureCamera.read(OriginalImageMat);

    if (OriginalImageMat.empty()) return;

    cv::resize(OriginalImageMat, ResizedImageMat, cv::Size(352,220), 0, 0, cv::INTER_CUBIC); //resizing the image to fit in the UI
    cv::flip(ResizedImageMat, ResizedImageMat, 1); //eliminating the mirror effect

    //Add the picture to the processer
    int move = Processer->getMove(ResizedImageMat);
    //std::cout << "move: " << move <<std::endl;

    //Move the car
    if(prevmove == 0)
    {
        myRoad->moveCar(move);
    }
    prevmove = move;

    cv::cvtColor(ResizedImageMat, ResizedImageMat, CV_BGR2RGB); //converting the image to RGB
    cv::rectangle(ResizedImageMat,cv::Rect(0, 0, 100, 130),cv::Scalar(200));
    cv::rectangle(ResizedImageMat,cv::Rect(250,0,102,130),cv::Scalar(200));

    QImage OriginalImage((uchar*)ResizedImageMat.data,
                         ResizedImageMat.cols,
                         ResizedImageMat.rows,
                         ResizedImageMat.step,
                         QImage::Format_RGB888); //Creating the QImage for the label
    QImage NetworkSendImage = OriginalImage;
    NetworkSendImage = NetworkSendImage.scaledToHeight(165);

    ui->MyVideoLabel->setPixmap(QPixmap::fromImage(OriginalImage));

    //Sending number of lives and distance embedded in the image
    NetworkSendImage.setText("lives", QString::number(lives));
    NetworkSendImage.setText("distance", QString::number(distance));

    n->sendData(NetworkSendImage); //sending the image over the network

//    std::cerr << "processVideoAndUpdateQUI() elapsed time: " << ProcUpdateElapsedTime.elapsed() << " msec" << std::endl << std::endl;
}

//Public slot that receives the image from the networking thread
void MainWindow::receiveNetworkImage(QImage q)
{
    if (!gameStarted)
    {
        //Start the game
        timer.start(Settings::FREQUENCY);
        gameStarted = true;
    }
    ui->NetworkCamVideo->setPixmap(QPixmap::fromImage(q)); //putting the received image to the gui
    if(q.text("lives").toInt()>=0) ui->NetworkLifeLCD->display(q.text("lives"));
    else lose();
    ui->NetworkDistLCD->display(q.text("distance"));
}

MainWindow::~MainWindow()
{
    delete ui;
    delete ProcessTimer;
    delete Processer;
    delete n;
    delete scene;
    delete myCar;
    delete myRoad;
}

void MainWindow::closeVideoStream()
{
    ProcessTimer->stop();
    //std::cout << "Video process timer stopped" <<std::endl;
    CaptureCamera.release();
    //std::cout << "Camera released" <<std::endl;
}

void MainWindow::restart()
{
        delete myRoad;
        myRoad = new Road();
        lives = Settings::STARTLIFE;
        ui->MyLifeLCD->display(lives);
        distance = 0;
        ui->MyDistLCD->display(distance);
        scene->addItem(myRoad);
        timer.start(Settings::FREQUENCY);
}

// Kezeli a billentyűlenyomást
void MainWindow::keyPressEvent(QKeyEvent *event){
    switch (event->key())
    {
        case Qt::Key_Right:
                myRoad->moveCar(1); //turn right;
            break;
        case Qt::Key_Left:
                myRoad->moveCar(-1); //turn left;
            break;
        case Qt::Key_Escape:
            closeVideoStream();
            close();
            exit(0);
            break;
        default:
            break;
    }
}
<|endoftext|>