<commit_before>/*
 * bench_psi.cpp
 *
 *  Created on: Nov 10, 2014
 *      Author: mzohner
 */

#include "bench_psi.h"

int32_t main(int32_t argc, char** argv) {
	benchroutine(argc, argv);
}

int32_t benchroutine(int32_t argc, char** argv) {
	uint32_t nelements=0, elebytelen=4, symsecbits=128,
			intersect_size, i, ntasks=1, runs=1, j, nclients=2, pnelements;
	uint8_t *elements, *intersection;
	string address = "127.0.0.1";
	uint16_t port=7766;
	timeval begin, end;
	vector<CSocket> sockfd(ntasks);
	field_type ftype = ECC_FIELD;
	role_type role = (role_type) 0;
	uint64_t bytes_sent=0, bytes_received=0, mbfac;
	psi_prot protocol;
	double epsilon=1.2;
	bool cardinality=false;
	bool detailed_timings = false;

	mbfac=1024*1024;

	read_bench_options(&argc, &argv, &role, &nelements, &elebytelen, &symsecbits,
			&address, &port, &ntasks, &protocol, &nclients, &epsilon, &cardinality, &ftype,
			&detailed_timings);

	if(role == SERVER) {
		if(protocol == TTP) {
			ntasks = nclients;
			sockfd.resize(ntasks);
		}
		listen(address.c_str(), port, sockfd.data(), ntasks);
	} else {
		for(i = 0; i < ntasks; i++)
			connect(address.c_str(), port, sockfd[i]);
	}

	crypto crypto(symsecbits, (uint8_t*) const_seed);

	//exchange number of items, bit-length of items, symmetric security parameter and protocol to make sure the parameters are correct
	if(protocol != TTP) {
		pnelements = exchange_information(nelements, elebytelen, symsecbits, ntasks, protocol, sockfd[0]);
	}

	if(protocol != TTP || role != SERVER) {
		elements = (uint8_t*) calloc(nelements * elebytelen, sizeof(uint8_t));
		crypto.gen_rnd(elements, elebytelen * nelements);
	}

#ifdef PRINT_INPUT_ELEMENTS
	for(i = 0; i < nelements; i++) {
		cout << "Element " << i << ": " << (hex);
		for(j = 0; j < elebytelen; j++)
			cout << (uint32_t) elements[i*elebytelen + j];
		cout << (dec) << endl;
	}
#endif

#ifndef BATCH
	cout << "Benchmarking protocol " << protocol << " on " << runs << " runs" << endl;
#endif
	gettimeofday(&begin, NULL);
	for(i = 0; i < runs; i++) {
		switch(protocol) {
		case NAIVE:
			naivepsi(role, nelements, pnelements, elebytelen, elements, &intersection, &crypto, sockfd.data(), ntasks);
			break;
		case TTP:
			ttppsi(role, nelements, elebytelen, elements, &intersection, &crypto, sockfd.data(), nclients, cardinality); break;
		case DH_ECC:
			intersect_size = dhpsi(role, nelements, pnelements, elebytelen, elements, &intersection, &crypto, sockfd.data(),
					ntasks, cardinality, ftype);
			break;
		case OT_PSI:
			intersect_size = otpsi(role, nelements, pnelements, elebytelen, elements, &intersection, &crypto, sockfd.data(),
					ntasks, epsilon, detailed_timings);
			break;
		default:break;
		}
	}
	gettimeofday(&end, NULL);

	for(i = 0; i < sockfd.size(); i++) {
		bytes_sent += sockfd[i].get_bytes_sent();
		bytes_received += sockfd[i].get_bytes_received();
	}
#ifdef BATCH
	cout << getMillies(begin, end) << "\t" << ((double) bytes_sent + bytes_received)/mbfac << endl;

#else
	cout << "Required time:\t" << fixed << std::setprecision(1) << getMillies(begin, end)/1000 << " s" << endl;
	cout << "Data sent:\t" <<	((double)bytes_sent)/mbfac << " MB" << endl;
	cout << "Data received:\t" << ((double)bytes_received)/mbfac << " MB" << endl;
#endif

#ifdef PRINT_INTERSECTION
	cout << "Found " << intersect_size << " intersecting elements" << endl;
		if(!cardinality) {
		for(i = 0; i < intersect_size; i++) {
			for(j = 0; j < elebytelen; j++) {
				cout << (hex) << (uint32_t) intersection[i * elebytelen + j] << (dec);
			}
			cout << endl;
		}
	}
#endif
	if(protocol != TTP || role != SERVER) {
		free(elements);
	}
	return 0;
}

int32_t read_bench_options(int32_t* argcp, char*** argvp, role_type* role, uint32_t* nelements, uint32_t* bytelen,
		uint32_t* secparam, string* address, uint16_t* port, uint32_t* ntasks, psi_prot* protocol, uint32_t* nclients,
		double* epsilon, bool* cardinality, field_type* ftype, bool* detailed_timings) {

	uint32_t int_role=0, int_port=0, int_protocol=0;
	bool useffc=false;

	parsing_ctx options[] = {{(void*) &int_role, T_NUM, 'r', "Role: 0/1", true, false},
			{(void*) &int_protocol, T_NUM, 'p', "PSI protocol (0: Naive, 1: TTP, 2: DH, 3: OT)", true, false},
			{(void*) nelements, T_NUM, 'n', "Number of elements", true, false},
			{(void*) bytelen, T_NUM, 'b', "Byte length of elements", true, false},
			{(void*) secparam, T_NUM, 's', "Symmetric Security Bits (default: 128)", false, false},
			{(void*) address, T_STR, 'a', "Server IP-address (needed by both, client and server)", false, false},
			{(void*) &int_port, T_NUM, 'o', "Port", false, false},
			{(void*) ntasks, T_NUM, 't', "Number of threads", false, false},
			{(void*) nclients, T_NUM, 'c', "Number of clients for TTP based protocol", false, false},
			{(void*) epsilon, T_DOUBLE, 'e', "Epsilon in Cuckoo hashing", false, false},
			{(void*) cardinality, T_FLAG, 'y', "Compute cardinality (only for DH and TTP PSI)", false, false},
			{(void*) &useffc, T_FLAG, 'f', "Use finite-field cryptography", false, false},
			{(void*) detailed_timings, T_FLAG, 'd', "Flag: Enable Detailed Timings", false, false}
	};

	if(!parse_options(argcp, argvp, options, sizeof(options)/sizeof(parsing_ctx))) {
		print_usage(argvp[0][0], options, sizeof(options)/sizeof(parsing_ctx));
		cout << "Exiting" << endl;
		exit(0);
	}

	assert(int_role < 2);
	*role = (role_type) int_role;

	assert(int_protocol < PROT_LAST);
	*protocol = (psi_prot) int_protocol;

	if(int_port != 0) {
		assert(int_port < 1<<(sizeof(uint16_t)*8));
		*port = (uint16_t) int_port;
	}

	if(useffc) {
		*ftype = P_FIELD;
	}

	return 1;
}

<commit_msg>Fix for multi-threading<commit_after>/*
 * bench_psi.cpp
 *
 *  Created on: Nov 10, 2014
 *      Author: mzohner
 */

#include "bench_psi.h"

int32_t main(int32_t argc, char** argv) {
	benchroutine(argc, argv);
}

int32_t benchroutine(int32_t argc, char** argv) {
	uint32_t nelements=0, elebytelen=4, symsecbits=128,
			intersect_size, i, ntasks=1, runs=1, j, nclients=2, pnelements;
	uint8_t *elements, *intersection;
	string address = "127.0.0.1";
	uint16_t port=7766;
	timeval begin, end;
	vector<CSocket> sockfd;
	field_type ftype = ECC_FIELD;
	role_type role = (role_type) 0;
	uint64_t bytes_sent=0, bytes_received=0, mbfac;
	psi_prot protocol;
	double epsilon=1.2;
	bool cardinality=false;
	bool detailed_timings = false;

	mbfac=1024*1024;

	read_bench_options(&argc, &argv, &role, &nelements, &elebytelen, &symsecbits,
			&address, &port, &ntasks, &protocol, &nclients, &epsilon, &cardinality, &ftype,
			&detailed_timings);

	sockfd.resize(ntasks);
	if(role == SERVER) {
		if(protocol == TTP) {
			ntasks = nclients;
			sockfd.resize(ntasks);
		}
		listen(address.c_str(), port, sockfd.data(), ntasks);
	} else {
		for(i = 0; i < ntasks; i++)
			connect(address.c_str(), port, sockfd[i]);
	}

	crypto crypto(symsecbits, (uint8_t*) const_seed);

	//exchange number of items, bit-length of items, symmetric security parameter and protocol to make sure the parameters are correct
	if(protocol != TTP) {
		pnelements = exchange_information(nelements, elebytelen, symsecbits, ntasks, protocol, sockfd[0]);
	}

	if(protocol != TTP || role != SERVER) {
		elements = (uint8_t*) calloc(nelements * elebytelen, sizeof(uint8_t));
		crypto.gen_rnd(elements, elebytelen * nelements);
	}

#ifdef PRINT_INPUT_ELEMENTS
	for(i = 0; i < nelements; i++) {
		cout << "Element " << i << ": " << (hex);
		for(j = 0; j < elebytelen; j++)
			cout << (uint32_t) elements[i*elebytelen + j];
		cout << (dec) << endl;
	}
#endif

#ifndef BATCH
	cout << "Benchmarking protocol " << protocol << " on " << runs << " runs" << endl;
#endif
	gettimeofday(&begin, NULL);
	for(i = 0; i < runs; i++) {
		switch(protocol) {
		case NAIVE:
			naivepsi(role, nelements, pnelements, elebytelen, elements, &intersection, &crypto, sockfd.data(), ntasks);
			break;
		case TTP:
			ttppsi(role, nelements, elebytelen, elements, &intersection, &crypto, sockfd.data(), nclients, cardinality); break;
		case DH_ECC:
			intersect_size = dhpsi(role, nelements, pnelements, elebytelen, elements, &intersection, &crypto, sockfd.data(),
					ntasks, cardinality, ftype);
			break;
		case OT_PSI:
			intersect_size = otpsi(role, nelements, pnelements, elebytelen, elements, &intersection, &crypto, sockfd.data(),
					ntasks, epsilon, detailed_timings);
			break;
		default:break;
		}
	}
	gettimeofday(&end, NULL);

	for(i = 0; i < sockfd.size(); i++) {
		bytes_sent += sockfd[i].get_bytes_sent();
		bytes_received += sockfd[i].get_bytes_received();
	}
#ifdef BATCH
	cout << getMillies(begin, end) << "\t" << ((double) bytes_sent + bytes_received)/mbfac << endl;

#else
	cout << "Required time:\t" << fixed << std::setprecision(1) << getMillies(begin, end)/1000 << " s" << endl;
	cout << "Data sent:\t" <<	((double)bytes_sent)/mbfac << " MB" << endl;
	cout << "Data received:\t" << ((double)bytes_received)/mbfac << " MB" << endl;
#endif

#ifdef PRINT_INTERSECTION
	cout << "Found " << intersect_size << " intersecting elements" << endl;
		if(!cardinality) {
		for(i = 0; i < intersect_size; i++) {
			for(j = 0; j < elebytelen; j++) {
				cout << (hex) << (uint32_t) intersection[i * elebytelen + j] << (dec);
			}
			cout << endl;
		}
	}
#endif
	if(protocol != TTP || role != SERVER) {
		free(elements);
	}
	return 0;
}

int32_t read_bench_options(int32_t* argcp, char*** argvp, role_type* role, uint32_t* nelements, uint32_t* bytelen,
		uint32_t* secparam, string* address, uint16_t* port, uint32_t* ntasks, psi_prot* protocol, uint32_t* nclients,
		double* epsilon, bool* cardinality, field_type* ftype, bool* detailed_timings) {

	uint32_t int_role=0, int_port=0, int_protocol=0;
	bool useffc=false;

	parsing_ctx options[] = {{(void*) &int_role, T_NUM, 'r', "Role: 0/1", true, false},
			{(void*) &int_protocol, T_NUM, 'p', "PSI protocol (0: Naive, 1: TTP, 2: DH, 3: OT)", true, false},
			{(void*) nelements, T_NUM, 'n', "Number of elements", true, false},
			{(void*) bytelen, T_NUM, 'b', "Byte length of elements", true, false},
			{(void*) secparam, T_NUM, 's', "Symmetric Security Bits (default: 128)", false, false},
			{(void*) address, T_STR, 'a', "Server IP-address (needed by both, client and server)", false, false},
			{(void*) &int_port, T_NUM, 'o', "Port", false, false},
			{(void*) ntasks, T_NUM, 't', "Number of threads", false, false},
			{(void*) nclients, T_NUM, 'c', "Number of clients for TTP based protocol", false, false},
			{(void*) epsilon, T_DOUBLE, 'e', "Epsilon in Cuckoo hashing", false, false},
			{(void*) cardinality, T_FLAG, 'y', "Compute cardinality (only for DH and TTP PSI)", false, false},
			{(void*) &useffc, T_FLAG, 'f', "Use finite-field cryptography", false, false},
			{(void*) detailed_timings, T_FLAG, 'd', "Flag: Enable Detailed Timings", false, false}
	};

	if(!parse_options(argcp, argvp, options, sizeof(options)/sizeof(parsing_ctx))) {
		print_usage(argvp[0][0], options, sizeof(options)/sizeof(parsing_ctx));
		cout << "Exiting" << endl;
		exit(0);
	}

	assert(int_role < 2);
	*role = (role_type) int_role;

	assert(int_protocol < PROT_LAST);
	*protocol = (psi_prot) int_protocol;

	if(int_port != 0) {
		assert(int_port < 1<<(sizeof(uint16_t)*8));
		*port = (uint16_t) int_port;
	}

	if(useffc) {
		*ftype = P_FIELD;
	}

	return 1;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: viewappletshape.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include <canvas/verbosetrace.hxx>
#include <canvas/debug.hxx>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/range/b2irange.hxx>
#include <basegfx/tools/canvastools.hxx>

#include <cppcanvas/spritecanvas.hxx>
#include <canvas/canvastools.hxx>

#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/awt/WindowDescriptor.hpp>
#include <com/sun/star/awt/XToolkit.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>

#include "viewappletshape.hxx"
#include "tools.hxx"

using namespace ::com::sun::star;

namespace slideshow
{
    namespace internal
    {
        ViewAppletShape::ViewAppletShape( const ViewLayerSharedPtr&                       rViewLayer,
                                          const uno::Reference< drawing::XShape >&        rxShape,
                                          const ::rtl::OUString&                          rServiceName,
                                          const char**                                    pPropCopyTable,
                                          sal_Size                                        nNumPropEntries,
                                          const uno::Reference< uno::XComponentContext >& rxContext ) :
            mpViewLayer( rViewLayer ),
            mxViewer(),
            mxFrame(),
            mxComponentContext( rxContext )
        {
            ENSURE_AND_THROW( rxShape.is(), "ViewAppletShape::ViewAppletShape(): Invalid Shape" );
            ENSURE_AND_THROW( mpViewLayer, "ViewAppletShape::ViewAppletShape(): Invalid View" );
            ENSURE_AND_THROW( mpViewLayer->getCanvas(), "ViewAppletShape::ViewAppletShape(): Invalid ViewLayer canvas" );
            ENSURE_AND_THROW( mxComponentContext.is(), "ViewAppletShape::ViewAppletShape(): Invalid component context" );

            uno::Reference<lang::XMultiComponentFactory> xFactory(
                mxComponentContext->getServiceManager(),
                uno::UNO_QUERY_THROW );

            mxViewer.set( xFactory->createInstanceWithContext( rServiceName,
                                                               mxComponentContext),
                          uno::UNO_QUERY_THROW );

            uno::Reference< beans::XPropertySet > xShapePropSet( rxShape,
                                                                 uno::UNO_QUERY_THROW );
            uno::Reference< beans::XPropertySet > mxViewerPropSet( mxViewer,
                                                                   uno::UNO_QUERY_THROW );

            // copy shape properties to applet viewer
            ::rtl::OUString aPropName;
            for( sal_Size i=0; i<nNumPropEntries; ++i )
            {
                aPropName = ::rtl::OUString::createFromAscii( pPropCopyTable[i] );
                mxViewerPropSet->setPropertyValue( aPropName,
                                                   xShapePropSet->getPropertyValue(
                                                       aPropName ));
            }
        }

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

        ViewAppletShape::~ViewAppletShape()
        {
            try
            {
                endApplet();
            }
            catch (uno::Exception &)
            {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
        }

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

        ViewLayerSharedPtr ViewAppletShape::getViewLayer() const
        {
            return mpViewLayer;
        }

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

        bool ViewAppletShape::startApplet( const ::basegfx::B2DRectangle& rBounds )
        {
            ENSURE_AND_RETURN( mpViewLayer && mpViewLayer->getCanvas() && mpViewLayer->getCanvas()->getUNOCanvas().is(),
                               "ViewAppletShape::startApplet(): Invalid or disposed view" );
            try
            {
                ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();

                uno::Reference< beans::XPropertySet > xPropSet( pCanvas->getUNOCanvas()->getDevice(),
                                                                uno::UNO_QUERY_THROW );

                uno::Reference< awt::XWindow2 > xParentWindow(
                    xPropSet->getPropertyValue(
                        ::rtl::OUString::createFromAscii( "Window" )),
                    uno::UNO_QUERY_THROW );

                uno::Reference<lang::XMultiComponentFactory> xFactory(
                    mxComponentContext->getServiceManager() );

                if( xFactory.is() )
                {
                    // create an awt window to contain the applet
                    // ==========================================

                    uno::Reference< awt::XToolkit > xToolkit(
                        xFactory->createInstanceWithContext(
                            ::rtl::OUString::createFromAscii( "com.sun.star.awt.Toolkit" ),
                            mxComponentContext ),
                        uno::UNO_QUERY_THROW );

                    awt::WindowDescriptor aOwnWinDescriptor( awt::WindowClass_SIMPLE,
                                                             ::rtl::OUString(),
                                                             uno::Reference< awt::XWindowPeer >(xParentWindow,
                                                                                uno::UNO_QUERY_THROW),
                                                             0,
                                                             awt::Rectangle(),
                                                             awt::WindowAttribute::SHOW
                                                             | awt::VclWindowPeerAttribute::CLIPCHILDREN );

                    uno::Reference< awt::XWindowPeer > xNewWinPeer(
                        xToolkit->createWindow( aOwnWinDescriptor ));
                    uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer,
                                                               uno::UNO_QUERY_THROW );

                    // create a frame, and load the applet into it
                    // ===========================================

                    mxFrame.set(
                        xFactory->createInstanceWithContext(
                            ::rtl::OUString::createFromAscii( "com.sun.star.frame.Frame" ),
                            mxComponentContext ),
                        uno::UNO_QUERY_THROW );

                    mxFrame->initialize( xOwnWindow );

                    uno::Reference < frame::XSynchronousFrameLoader > xLoader( mxViewer,
                                                                               uno::UNO_QUERY_THROW );
                    xLoader->load( uno::Sequence < beans::PropertyValue >(),
                                   mxFrame );

                    // resize surrounding window and applet to current shape size
                    // ==========================================================

                    ::basegfx::B2DRange aTmpRange;
                    ::canvas::tools::calcTransformedRectBounds( aTmpRange,
                                                                rBounds,
                                                                mpViewLayer->getTransformation() );
                    const ::basegfx::B2IRange& rPixelBounds(
                        ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));

                    uno::Reference< awt::XWindow > xSurroundingWindow( mxFrame->getContainerWindow() );
                    if( xSurroundingWindow.is() )
                        xSurroundingWindow->setPosSize( static_cast<sal_Int32>(rPixelBounds.getMinX()),
                                                        static_cast<sal_Int32>(rPixelBounds.getMinY()),
                                                        static_cast<sal_Int32>(rPixelBounds.getWidth()),
                                                        static_cast<sal_Int32>(rPixelBounds.getHeight()),
                                                        awt::PosSize::POSSIZE );

                    uno::Reference< awt::XWindow > xAppletWindow( mxFrame->getComponentWindow() );
                    if( xAppletWindow.is() )
                        xAppletWindow->setPosSize( 0, 0,
                                                   static_cast<sal_Int32>(rPixelBounds.getWidth()),
                                                   static_cast<sal_Int32>(rPixelBounds.getHeight()),
                                                   awt::PosSize::POSSIZE );
                }
            }
            catch (uno::Exception &)
            {
                return false;
            }

            return true;
        }

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

        void ViewAppletShape::endApplet()
        {
            uno::Reference<util::XCloseable> xCloseable(
                mxFrame,
                uno::UNO_QUERY );

            if( xCloseable.is() )
            {
                xCloseable->close( sal_True );
                mxFrame.clear();
            }
        }

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

        bool ViewAppletShape::render( const ::basegfx::B2DRectangle& rBounds ) const
        {
            ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();

            if( !pCanvas )
                return false;

            if( !mxFrame.is() )
            {
                // fill the shape background with black
                fillRect( pCanvas,
                          rBounds,
                          0xFFFFFFFFU );
            }

            return true;
        }

        bool ViewAppletShape::resize( const ::basegfx::B2DRectangle& rBounds ) const
        {
            if( !mxFrame.is() )
                return false;

            ::basegfx::B2DRange aTmpRange;
            ::canvas::tools::calcTransformedRectBounds( aTmpRange,
                                                        rBounds,
                                                        mpViewLayer->getTransformation() );
            const ::basegfx::B2IRange& rPixelBounds(
                ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));

            uno::Reference< awt::XWindow > xFrameWindow( mxFrame->getContainerWindow() );
            if( xFrameWindow.is() )
                xFrameWindow->setPosSize( static_cast<sal_Int32>(rPixelBounds.getMinX()),
                                          static_cast<sal_Int32>(rPixelBounds.getMinY()),
                                          static_cast<sal_Int32>(rPixelBounds.getWidth()),
                                          static_cast<sal_Int32>(rPixelBounds.getHeight()),
                                          awt::PosSize::POSSIZE );

            uno::Reference< awt::XWindow > xAppletWindow( mxFrame->getComponentWindow() );
            if( xAppletWindow.is() )
                xAppletWindow->setPosSize( 0, 0,
                                           static_cast<sal_Int32>(rPixelBounds.getWidth()),
                                           static_cast<sal_Int32>(rPixelBounds.getHeight()),
                                           awt::PosSize::POSSIZE );

            return true;
        }
    }
}
<commit_msg>INTEGRATION: CWS canvas05 (1.2.18); FILE MERGED 2008/04/21 07:55:09 thb 1.2.18.2: RESYNC: (1.2-1.3); FILE MERGED 2007/10/01 13:49:13 thb 1.2.18.1: #i79258# Merge from CWS picom<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: viewappletshape.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include <canvas/verbosetrace.hxx>
#include <tools/diagnose_ex.h>
#include <canvas/debug.hxx>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/range/b2irange.hxx>
#include <basegfx/tools/canvastools.hxx>

#include <cppcanvas/spritecanvas.hxx>
#include <canvas/canvastools.hxx>

#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/awt/WindowDescriptor.hpp>
#include <com/sun/star/awt/XToolkit.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>

#include "viewappletshape.hxx"
#include "tools.hxx"

using namespace ::com::sun::star;

namespace slideshow
{
    namespace internal
    {
        ViewAppletShape::ViewAppletShape( const ViewLayerSharedPtr&                       rViewLayer,
                                          const uno::Reference< drawing::XShape >&        rxShape,
                                          const ::rtl::OUString&                          rServiceName,
                                          const char**                                    pPropCopyTable,
                                          sal_Size                                        nNumPropEntries,
                                          const uno::Reference< uno::XComponentContext >& rxContext ) :
            mpViewLayer( rViewLayer ),
            mxViewer(),
            mxFrame(),
            mxComponentContext( rxContext )
        {
            ENSURE_OR_THROW( rxShape.is(), "ViewAppletShape::ViewAppletShape(): Invalid Shape" );
            ENSURE_OR_THROW( mpViewLayer, "ViewAppletShape::ViewAppletShape(): Invalid View" );
            ENSURE_OR_THROW( mpViewLayer->getCanvas(), "ViewAppletShape::ViewAppletShape(): Invalid ViewLayer canvas" );
            ENSURE_OR_THROW( mxComponentContext.is(), "ViewAppletShape::ViewAppletShape(): Invalid component context" );

            uno::Reference<lang::XMultiComponentFactory> xFactory(
                mxComponentContext->getServiceManager(),
                uno::UNO_QUERY_THROW );

            mxViewer.set( xFactory->createInstanceWithContext( rServiceName,
                                                               mxComponentContext),
                          uno::UNO_QUERY_THROW );

            uno::Reference< beans::XPropertySet > xShapePropSet( rxShape,
                                                                 uno::UNO_QUERY_THROW );
            uno::Reference< beans::XPropertySet > mxViewerPropSet( mxViewer,
                                                                   uno::UNO_QUERY_THROW );

            // copy shape properties to applet viewer
            ::rtl::OUString aPropName;
            for( sal_Size i=0; i<nNumPropEntries; ++i )
            {
                aPropName = ::rtl::OUString::createFromAscii( pPropCopyTable[i] );
                mxViewerPropSet->setPropertyValue( aPropName,
                                                   xShapePropSet->getPropertyValue(
                                                       aPropName ));
            }
        }

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

        ViewAppletShape::~ViewAppletShape()
        {
            try
            {
                endApplet();
            }
            catch (uno::Exception &)
            {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
        }

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

        ViewLayerSharedPtr ViewAppletShape::getViewLayer() const
        {
            return mpViewLayer;
        }

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

        bool ViewAppletShape::startApplet( const ::basegfx::B2DRectangle& rBounds )
        {
            ENSURE_OR_RETURN( mpViewLayer && mpViewLayer->getCanvas() && mpViewLayer->getCanvas()->getUNOCanvas().is(),
                               "ViewAppletShape::startApplet(): Invalid or disposed view" );
            try
            {
                ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();

                uno::Reference< beans::XPropertySet > xPropSet( pCanvas->getUNOCanvas()->getDevice(),
                                                                uno::UNO_QUERY_THROW );

                uno::Reference< awt::XWindow2 > xParentWindow(
                    xPropSet->getPropertyValue(
                        ::rtl::OUString::createFromAscii( "Window" )),
                    uno::UNO_QUERY_THROW );

                uno::Reference<lang::XMultiComponentFactory> xFactory(
                    mxComponentContext->getServiceManager() );

                if( xFactory.is() )
                {
                    // create an awt window to contain the applet
                    // ==========================================

                    uno::Reference< awt::XToolkit > xToolkit(
                        xFactory->createInstanceWithContext(
                            ::rtl::OUString::createFromAscii( "com.sun.star.awt.Toolkit" ),
                            mxComponentContext ),
                        uno::UNO_QUERY_THROW );

                    awt::WindowDescriptor aOwnWinDescriptor( awt::WindowClass_SIMPLE,
                                                             ::rtl::OUString(),
                                                             uno::Reference< awt::XWindowPeer >(xParentWindow,
                                                                                uno::UNO_QUERY_THROW),
                                                             0,
                                                             awt::Rectangle(),
                                                             awt::WindowAttribute::SHOW
                                                             | awt::VclWindowPeerAttribute::CLIPCHILDREN );

                    uno::Reference< awt::XWindowPeer > xNewWinPeer(
                        xToolkit->createWindow( aOwnWinDescriptor ));
                    uno::Reference< awt::XWindow > xOwnWindow( xNewWinPeer,
                                                               uno::UNO_QUERY_THROW );

                    // create a frame, and load the applet into it
                    // ===========================================

                    mxFrame.set(
                        xFactory->createInstanceWithContext(
                            ::rtl::OUString::createFromAscii( "com.sun.star.frame.Frame" ),
                            mxComponentContext ),
                        uno::UNO_QUERY_THROW );

                    mxFrame->initialize( xOwnWindow );

                    uno::Reference < frame::XSynchronousFrameLoader > xLoader( mxViewer,
                                                                               uno::UNO_QUERY_THROW );
                    xLoader->load( uno::Sequence < beans::PropertyValue >(),
                                   mxFrame );

                    // resize surrounding window and applet to current shape size
                    // ==========================================================

                    ::basegfx::B2DRange aTmpRange;
                    ::canvas::tools::calcTransformedRectBounds( aTmpRange,
                                                                rBounds,
                                                                mpViewLayer->getTransformation() );
                    const ::basegfx::B2IRange& rPixelBounds(
                        ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));

                    uno::Reference< awt::XWindow > xSurroundingWindow( mxFrame->getContainerWindow() );
                    if( xSurroundingWindow.is() )
                        xSurroundingWindow->setPosSize( static_cast<sal_Int32>(rPixelBounds.getMinX()),
                                                        static_cast<sal_Int32>(rPixelBounds.getMinY()),
                                                        static_cast<sal_Int32>(rPixelBounds.getWidth()),
                                                        static_cast<sal_Int32>(rPixelBounds.getHeight()),
                                                        awt::PosSize::POSSIZE );

                    uno::Reference< awt::XWindow > xAppletWindow( mxFrame->getComponentWindow() );
                    if( xAppletWindow.is() )
                        xAppletWindow->setPosSize( 0, 0,
                                                   static_cast<sal_Int32>(rPixelBounds.getWidth()),
                                                   static_cast<sal_Int32>(rPixelBounds.getHeight()),
                                                   awt::PosSize::POSSIZE );
                }
            }
            catch (uno::Exception &)
            {
                return false;
            }

            return true;
        }

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

        void ViewAppletShape::endApplet()
        {
            uno::Reference<util::XCloseable> xCloseable(
                mxFrame,
                uno::UNO_QUERY );

            if( xCloseable.is() )
            {
                xCloseable->close( sal_True );
                mxFrame.clear();
            }
        }

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

        bool ViewAppletShape::render( const ::basegfx::B2DRectangle& rBounds ) const
        {
            ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();

            if( !pCanvas )
                return false;

            if( !mxFrame.is() )
            {
                // fill the shape background with black
                fillRect( pCanvas,
                          rBounds,
                          0xFFFFFFFFU );
            }

            return true;
        }

        bool ViewAppletShape::resize( const ::basegfx::B2DRectangle& rBounds ) const
        {
            if( !mxFrame.is() )
                return false;

            ::basegfx::B2DRange aTmpRange;
            ::canvas::tools::calcTransformedRectBounds( aTmpRange,
                                                        rBounds,
                                                        mpViewLayer->getTransformation() );
            const ::basegfx::B2IRange& rPixelBounds(
                ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));

            uno::Reference< awt::XWindow > xFrameWindow( mxFrame->getContainerWindow() );
            if( xFrameWindow.is() )
                xFrameWindow->setPosSize( static_cast<sal_Int32>(rPixelBounds.getMinX()),
                                          static_cast<sal_Int32>(rPixelBounds.getMinY()),
                                          static_cast<sal_Int32>(rPixelBounds.getWidth()),
                                          static_cast<sal_Int32>(rPixelBounds.getHeight()),
                                          awt::PosSize::POSSIZE );

            uno::Reference< awt::XWindow > xAppletWindow( mxFrame->getComponentWindow() );
            if( xAppletWindow.is() )
                xAppletWindow->setPosSize( 0, 0,
                                           static_cast<sal_Int32>(rPixelBounds.getWidth()),
                                           static_cast<sal_Int32>(rPixelBounds.getHeight()),
                                           awt::PosSize::POSSIZE );

            return true;
        }
    }
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

You may use this sample code for anything you like, it is not covered by the
same license as the rest of the engine.
-----------------------------------------------------------------------------
*/

#include "DLight.h"

#include "OgreHardwareBufferManager.h"
#include "OgreCamera.h"
#include "OgreSceneNode.h"
#include "OgreLight.h"
#include "GeomUtils.h"
#include "LightMaterialGenerator.h"
#include "OgreTechnique.h"
#include "OgreSceneManager.h"

#define ENABLE_BIT(mask, flag) (mask) |= (flag)
#define DISABLE_BIT(mask, flag) (mask) &= ~(flag)

using namespace Ogre;
//-----------------------------------------------------------------------
DLight::DLight(MaterialGenerator *sys, Ogre::Light* parentLight):
    mParentLight(parentLight), bIgnoreWorld(false), mGenerator(sys), mPermutation(0)
{
	// Set up geometry
	// Allocate render operation
	mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
	mRenderOp.indexData = 0;
	mRenderOp.vertexData = 0;
	mRenderOp.useIndexes = true;

	updateFromParent();
}
//-----------------------------------------------------------------------
DLight::~DLight()
{
	// need to release IndexData and vertexData created for renderable
    delete mRenderOp.indexData;
    delete mRenderOp.vertexData;
}
//-----------------------------------------------------------------------
void DLight::setAttenuation(float c, float b, float a)
{
	// Set Attenuation parameter to shader
	//setCustomParameter(3, Vector4(c, b, a, 0));
	float outerRadius = mParentLight->getAttenuationRange();
	/// There is attenuation? Set material accordingly
	if(c != 1.0f || b != 0.0f || a != 0.0f)
	{
		ENABLE_BIT(mPermutation, LightMaterialGenerator::MI_ATTENUATED);
		if (mParentLight->getType() == Light::LT_POINT)
		{
			//// Calculate radius from Attenuation
			int threshold_level = 10;// difference of 10-15 levels deemed unnoticeable
			float threshold = 1.0f/((float)threshold_level/256.0f);

			//// Use quadratic formula to determine outer radius
			c = c-threshold;
			float d=sqrt(b*b-4*a*c);
			outerRadius = (-2*c)/(b+d);
			outerRadius *= 1.2;
		}
	}
	else
	{
		DISABLE_BIT(mPermutation,LightMaterialGenerator::MI_ATTENUATED);
	}

	rebuildGeometry(outerRadius);
}
//-----------------------------------------------------------------------
void DLight::setSpecularColour(const ColourValue &col)
{
	//setCustomParameter(2, Vector4(col.r, col.g, col.b, col.a));
	/// There is a specular component? Set material accordingly

	if(col.r != 0.0f || col.g != 0.0f || col.b != 0.0f)
		ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPECULAR);
	else
		DISABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPECULAR);

}
//-----------------------------------------------------------------------
void DLight::rebuildGeometry(float radius)
{
	//Disable all 3 bits
	DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_POINT);
	DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_SPOTLIGHT);
	DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_DIRECTIONAL);

	switch (mParentLight->getType())
	{
	case Light::LT_DIRECTIONAL:
		createRectangle2D();
        ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_DIRECTIONAL);
		break;
	case Light::LT_POINT:
		/// XXX some more intelligent expression for rings and segments
		createSphere(radius, 10, 10);
		ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_POINT);
		break;
	case Light::LT_SPOTLIGHT:
		Real height = mParentLight->getAttenuationRange();
		Radian coneRadiusAngle = mParentLight->getSpotlightOuterAngle() / 2;
        Real radius = Math::Tan(coneRadiusAngle) * height;
		createCone(radius, height, 20);
		ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPOTLIGHT);
		break;
	}
}
//-----------------------------------------------------------------------
void DLight::createRectangle2D()
{
	/// XXX this RenderOp should really be re-used between DLight objects,
	/// not generated every time
	delete mRenderOp.vertexData;
	delete mRenderOp.indexData;

	mRenderOp.vertexData = new VertexData();
    mRenderOp.indexData = 0;

	GeomUtils::createQuad(mRenderOp.vertexData);

    mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
    mRenderOp.useIndexes = false;

	// Set bounding
    setBoundingBox(AxisAlignedBox(-10000,-10000,-10000,10000,10000,10000));
	mRadius = 15000;
	bIgnoreWorld = true;
}
//-----------------------------------------------------------------------
void DLight::createSphere(float radius, int nRings, int nSegments)
{
	delete mRenderOp.vertexData;
	delete mRenderOp.indexData;
	mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
	mRenderOp.indexData = new IndexData();
	mRenderOp.vertexData = new VertexData();
	mRenderOp.useIndexes = true;

	GeomUtils::createSphere(mRenderOp.vertexData, mRenderOp.indexData
		, radius
		, nRings, nSegments
		, false // no normals
		, false // no texture coordinates
		);

	// Set bounding box and sphere
	setBoundingBox( AxisAlignedBox( Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius) ) );
	mRadius = radius;
	bIgnoreWorld = false;
}
//-----------------------------------------------------------------------
void DLight::createCone(float radius, float height, int nVerticesInBase)
{
	delete mRenderOp.vertexData;
	delete mRenderOp.indexData;
	mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
	mRenderOp.indexData = new IndexData();
	mRenderOp.vertexData = new VertexData();
	mRenderOp.useIndexes = true;

	GeomUtils::createCone(mRenderOp.vertexData, mRenderOp.indexData
		, radius
		, height, nVerticesInBase);

	// Set bounding box and sphere
	setBoundingBox( AxisAlignedBox(
			Vector3(-radius, 0, -radius),
			Vector3(radius, height, radius) ) );

	mRadius = radius;
	bIgnoreWorld = false;
}
//-----------------------------------------------------------------------
Real DLight::getBoundingRadius(void) const
{
	return mRadius;
}
//-----------------------------------------------------------------------
Real DLight::getSquaredViewDepth(const Camera* cam) const
{
	if(bIgnoreWorld)
	{
		return 0.0f;
	}
	else
	{
		Vector3 dist = cam->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition();
		return dist.squaredLength();
	}
}
//-----------------------------------------------------------------------
const MaterialPtr& DLight::getMaterial(void) const
{
	return mGenerator->getMaterial(mPermutation);
}
//-----------------------------------------------------------------------
void DLight::getWorldTransforms(Matrix4* xform) const
{
	if (mParentLight->getType() == Light::LT_SPOTLIGHT)
	{
		Quaternion quat = Vector3::UNIT_Y.getRotationTo(mParentLight->getDerivedDirection());
		xform->makeTransform(mParentLight->getDerivedPosition(),
			Vector3::UNIT_SCALE, quat);
	}
	else
	{
		xform->makeTransform(mParentLight->getDerivedPosition(),
			Vector3::UNIT_SCALE, Quaternion::IDENTITY);
	}

}
//-----------------------------------------------------------------------
void DLight::updateFromParent()
{
	//TODO : Don't do this unless something changed
	setAttenuation(mParentLight->getAttenuationConstant(),
		mParentLight->getAttenuationLinear(), mParentLight->getAttenuationQuadric());
	setSpecularColour(mParentLight->getSpecularColour());

	if (getCastChadows())
	{
		ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SHADOW_CASTER);
	}
	else
	{
		DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_SHADOW_CASTER);
	}
}
//-----------------------------------------------------------------------
bool DLight::isCameraInsideLight(Ogre::Camera* camera)
{
	switch (mParentLight->getType())
	{
	case Ogre::Light::LT_DIRECTIONAL:
		return false;
	case Ogre::Light::LT_POINT:
		{
		Ogre::Real distanceFromLight = camera->getDerivedPosition()
			.distance(mParentLight->getDerivedPosition());
		//Small epsilon fix to account for near clip range and the fact that we aren't a true sphere.
		return distanceFromLight <= mRadius + camera->getNearClipDistance() + 0.1;
		}
	case Ogre::Light::LT_SPOTLIGHT:
		{
		Ogre::Vector3 lightToCamDir = camera->getDerivedPosition() - mParentLight->getDerivedPosition();
		Ogre::Real distanceFromLight = lightToCamDir.normalise();
		Ogre::Real cosAngle = lightToCamDir.dotProduct(mParentLight->getDerivedDirection());
		Ogre::Radian angle = Ogre::Math::ACos(cosAngle);
		return (distanceFromLight <= mParentLight->getAttenuationRange()) &&
			(angle < mParentLight->getSpotlightOuterAngle());
		}
	default:
		//Please the compiler
		return false;
	}
}
//-----------------------------------------------------------------------
bool DLight::getCastChadows() const
{
	return
		mParentLight->_getManager()->isShadowTechniqueInUse() &&
		mParentLight->getCastShadows() &&
		(mParentLight->getType() == Light::LT_DIRECTIONAL || mParentLight->getType() == Light::LT_SPOTLIGHT);
}
//-----------------------------------------------------------------------
void DLight::updateFromCamera(Ogre::Camera* camera)
{
	//Set shader params
	const Ogre::MaterialPtr& mat = getMaterial();
	if (!mat->isLoaded())
	{
		mat->load();
	}
	Ogre::Technique* tech = mat->getBestTechnique();
	Ogre::Vector3 farCorner = camera->getViewMatrix(true) * camera->getWorldSpaceCorners()[4];

	for (unsigned short i=0; i<tech->getNumPasses(); i++)
	{
		Ogre::Pass* pass = tech->getPass(i);
		// get the vertex shader parameters
		Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();
		// set the camera's far-top-right corner
		if (params->_findNamedConstantDefinition("farCorner"))
			params->setNamedConstant("farCorner", farCorner);

		params = pass->getFragmentProgramParameters();
		if (params->_findNamedConstantDefinition("farCorner"))
			params->setNamedConstant("farCorner", farCorner);

		//If inside light geometry, render back faces with CMPF_GREATER, otherwise normally
		if (mParentLight->getType() == Ogre::Light::LT_DIRECTIONAL)
		{
			pass->setCullingMode(Ogre::CULL_CLOCKWISE);
			pass->setDepthCheckEnabled(false);
		}
		else
		{
			pass->setDepthCheckEnabled(true);
			if (isCameraInsideLight(camera))
			{
				pass->setCullingMode(Ogre::CULL_ANTICLOCKWISE);
				pass->setDepthFunction(Ogre::CMPF_GREATER_EQUAL);
			}
			else
			{
				pass->setCullingMode(Ogre::CULL_CLOCKWISE);
				pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL);
			}
		}

		Camera shadowCam("ShadowCameraSetupCam", 0);
		shadowCam._notifyViewport(camera->getViewport());
		SceneManager* sm = mParentLight->_getManager();
		sm->getShadowCameraSetup()->getShadowCamera(sm,
			camera, camera->getViewport(), mParentLight, &shadowCam, 0);

		//Get the shadow camera position
		if (params->_findNamedConstantDefinition("shadowCamPos"))
		{
			params->setNamedConstant("shadowCamPos", shadowCam.getPosition());
		}
		if (params->_findNamedConstantDefinition("shadowFarClip"))
		{
			params->setNamedConstant("shadowFarClip", shadowCam.getFarClipDistance());
		}

	}
}
<commit_msg>Deferred Shading Demo : Fixed 'is camera inside light' test for spotlights.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

You may use this sample code for anything you like, it is not covered by the
same license as the rest of the engine.
-----------------------------------------------------------------------------
*/

#include "DLight.h"

#include "OgreHardwareBufferManager.h"
#include "OgreCamera.h"
#include "OgreSceneNode.h"
#include "OgreLight.h"
#include "GeomUtils.h"
#include "LightMaterialGenerator.h"
#include "OgreTechnique.h"
#include "OgreSceneManager.h"

#define ENABLE_BIT(mask, flag) (mask) |= (flag)
#define DISABLE_BIT(mask, flag) (mask) &= ~(flag)

using namespace Ogre;
//-----------------------------------------------------------------------
DLight::DLight(MaterialGenerator *sys, Ogre::Light* parentLight):
    mParentLight(parentLight), bIgnoreWorld(false), mGenerator(sys), mPermutation(0)
{
	// Set up geometry
	// Allocate render operation
	mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
	mRenderOp.indexData = 0;
	mRenderOp.vertexData = 0;
	mRenderOp.useIndexes = true;

	updateFromParent();
}
//-----------------------------------------------------------------------
DLight::~DLight()
{
	// need to release IndexData and vertexData created for renderable
    delete mRenderOp.indexData;
    delete mRenderOp.vertexData;
}
//-----------------------------------------------------------------------
void DLight::setAttenuation(float c, float b, float a)
{
	// Set Attenuation parameter to shader
	//setCustomParameter(3, Vector4(c, b, a, 0));
	float outerRadius = mParentLight->getAttenuationRange();
	/// There is attenuation? Set material accordingly
	if(c != 1.0f || b != 0.0f || a != 0.0f)
	{
		ENABLE_BIT(mPermutation, LightMaterialGenerator::MI_ATTENUATED);
		if (mParentLight->getType() == Light::LT_POINT)
		{
			//// Calculate radius from Attenuation
			int threshold_level = 10;// difference of 10-15 levels deemed unnoticeable
			float threshold = 1.0f/((float)threshold_level/256.0f);

			//// Use quadratic formula to determine outer radius
			c = c-threshold;
			float d=sqrt(b*b-4*a*c);
			outerRadius = (-2*c)/(b+d);
			outerRadius *= 1.2;
		}
	}
	else
	{
		DISABLE_BIT(mPermutation,LightMaterialGenerator::MI_ATTENUATED);
	}

	rebuildGeometry(outerRadius);
}
//-----------------------------------------------------------------------
void DLight::setSpecularColour(const ColourValue &col)
{
	//setCustomParameter(2, Vector4(col.r, col.g, col.b, col.a));
	/// There is a specular component? Set material accordingly

	if(col.r != 0.0f || col.g != 0.0f || col.b != 0.0f)
		ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPECULAR);
	else
		DISABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPECULAR);

}
//-----------------------------------------------------------------------
void DLight::rebuildGeometry(float radius)
{
	//Disable all 3 bits
	DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_POINT);
	DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_SPOTLIGHT);
	DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_DIRECTIONAL);

	switch (mParentLight->getType())
	{
	case Light::LT_DIRECTIONAL:
		createRectangle2D();
        ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_DIRECTIONAL);
		break;
	case Light::LT_POINT:
		/// XXX some more intelligent expression for rings and segments
		createSphere(radius, 10, 10);
		ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_POINT);
		break;
	case Light::LT_SPOTLIGHT:
		Real height = mParentLight->getAttenuationRange();
		Radian coneRadiusAngle = mParentLight->getSpotlightOuterAngle() / 2;
        Real radius = Math::Tan(coneRadiusAngle) * height;
		createCone(radius, height, 20);
		ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPOTLIGHT);
		break;
	}
}
//-----------------------------------------------------------------------
void DLight::createRectangle2D()
{
	/// XXX this RenderOp should really be re-used between DLight objects,
	/// not generated every time
	delete mRenderOp.vertexData;
	delete mRenderOp.indexData;

	mRenderOp.vertexData = new VertexData();
    mRenderOp.indexData = 0;

	GeomUtils::createQuad(mRenderOp.vertexData);

    mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
    mRenderOp.useIndexes = false;

	// Set bounding
    setBoundingBox(AxisAlignedBox(-10000,-10000,-10000,10000,10000,10000));
	mRadius = 15000;
	bIgnoreWorld = true;
}
//-----------------------------------------------------------------------
void DLight::createSphere(float radius, int nRings, int nSegments)
{
	delete mRenderOp.vertexData;
	delete mRenderOp.indexData;
	mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
	mRenderOp.indexData = new IndexData();
	mRenderOp.vertexData = new VertexData();
	mRenderOp.useIndexes = true;

	GeomUtils::createSphere(mRenderOp.vertexData, mRenderOp.indexData
		, radius
		, nRings, nSegments
		, false // no normals
		, false // no texture coordinates
		);

	// Set bounding box and sphere
	setBoundingBox( AxisAlignedBox( Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius) ) );
	mRadius = radius;
	bIgnoreWorld = false;
}
//-----------------------------------------------------------------------
void DLight::createCone(float radius, float height, int nVerticesInBase)
{
	delete mRenderOp.vertexData;
	delete mRenderOp.indexData;
	mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
	mRenderOp.indexData = new IndexData();
	mRenderOp.vertexData = new VertexData();
	mRenderOp.useIndexes = true;

	GeomUtils::createCone(mRenderOp.vertexData, mRenderOp.indexData
		, radius
		, height, nVerticesInBase);

	// Set bounding box and sphere
	setBoundingBox( AxisAlignedBox(
			Vector3(-radius, 0, -radius),
			Vector3(radius, height, radius) ) );

	mRadius = radius;
	bIgnoreWorld = false;
}
//-----------------------------------------------------------------------
Real DLight::getBoundingRadius(void) const
{
	return mRadius;
}
//-----------------------------------------------------------------------
Real DLight::getSquaredViewDepth(const Camera* cam) const
{
	if(bIgnoreWorld)
	{
		return 0.0f;
	}
	else
	{
		Vector3 dist = cam->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition();
		return dist.squaredLength();
	}
}
//-----------------------------------------------------------------------
const MaterialPtr& DLight::getMaterial(void) const
{
	return mGenerator->getMaterial(mPermutation);
}
//-----------------------------------------------------------------------
void DLight::getWorldTransforms(Matrix4* xform) const
{
	if (mParentLight->getType() == Light::LT_SPOTLIGHT)
	{
		Quaternion quat = Vector3::UNIT_Y.getRotationTo(mParentLight->getDerivedDirection());
		xform->makeTransform(mParentLight->getDerivedPosition(),
			Vector3::UNIT_SCALE, quat);
	}
	else
	{
		xform->makeTransform(mParentLight->getDerivedPosition(),
			Vector3::UNIT_SCALE, Quaternion::IDENTITY);
	}

}
//-----------------------------------------------------------------------
void DLight::updateFromParent()
{
	//TODO : Don't do this unless something changed
	setAttenuation(mParentLight->getAttenuationConstant(),
		mParentLight->getAttenuationLinear(), mParentLight->getAttenuationQuadric());
	setSpecularColour(mParentLight->getSpecularColour());

	if (getCastChadows())
	{
		ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SHADOW_CASTER);
	}
	else
	{
		DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_SHADOW_CASTER);
	}
}
//-----------------------------------------------------------------------
bool DLight::isCameraInsideLight(Ogre::Camera* camera)
{
	switch (mParentLight->getType())
	{
	case Ogre::Light::LT_DIRECTIONAL:
		return false;
	case Ogre::Light::LT_POINT:
		{
		Ogre::Real distanceFromLight = camera->getDerivedPosition()
			.distance(mParentLight->getDerivedPosition());
		//Small epsilon fix to account for the fact that we aren't a true sphere.
		return distanceFromLight <= mRadius + camera->getNearClipDistance() + 0.1;
		}
	case Ogre::Light::LT_SPOTLIGHT:
		{
		Ogre::Vector3 lightPos = mParentLight->getDerivedPosition();
		Ogre::Vector3 lightDir = mParentLight->getDerivedDirection();
		Ogre::Radian attAngle = mParentLight->getSpotlightOuterAngle();

		//Extend the analytic cone's radius by the near clip range by moving its tip accordingly.
		//Some trigonometry needed here.
		Ogre::Vector3 clipRangeFix = -lightDir * (camera->getNearClipDistance() / Ogre::Math::Tan(attAngle/2));
		lightPos = lightPos + clipRangeFix;

		Ogre::Vector3 lightToCamDir = camera->getDerivedPosition() - lightPos;
		Ogre::Real distanceFromLight = lightToCamDir.normalise();

		Ogre::Real cosAngle = lightToCamDir.dotProduct(lightDir);
		Ogre::Radian angle = Ogre::Math::ACos(cosAngle);
		//Check whether we will see the cone from our current POV.
		return (distanceFromLight <= (mParentLight->getAttenuationRange() + clipRangeFix.length()))
			&& (angle <= attAngle);
		}
	default:
		//Please the compiler
		return false;
	}
}
//-----------------------------------------------------------------------
bool DLight::getCastChadows() const
{
	return
		mParentLight->_getManager()->isShadowTechniqueInUse() &&
		mParentLight->getCastShadows() &&
		(mParentLight->getType() == Light::LT_DIRECTIONAL || mParentLight->getType() == Light::LT_SPOTLIGHT);
}
//-----------------------------------------------------------------------
void DLight::updateFromCamera(Ogre::Camera* camera)
{
	//Set shader params
	const Ogre::MaterialPtr& mat = getMaterial();
	if (!mat->isLoaded())
	{
		mat->load();
	}
	Ogre::Technique* tech = mat->getBestTechnique();
	Ogre::Vector3 farCorner = camera->getViewMatrix(true) * camera->getWorldSpaceCorners()[4];

	for (unsigned short i=0; i<tech->getNumPasses(); i++)
	{
		Ogre::Pass* pass = tech->getPass(i);
		// get the vertex shader parameters
		Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();
		// set the camera's far-top-right corner
		if (params->_findNamedConstantDefinition("farCorner"))
			params->setNamedConstant("farCorner", farCorner);

		params = pass->getFragmentProgramParameters();
		if (params->_findNamedConstantDefinition("farCorner"))
			params->setNamedConstant("farCorner", farCorner);

		//If inside light geometry, render back faces with CMPF_GREATER, otherwise normally
		if (mParentLight->getType() == Ogre::Light::LT_DIRECTIONAL)
		{
			pass->setCullingMode(Ogre::CULL_CLOCKWISE);
			pass->setDepthCheckEnabled(false);
		}
		else
		{
			pass->setDepthCheckEnabled(true);
			if (isCameraInsideLight(camera))
			{
				pass->setCullingMode(Ogre::CULL_ANTICLOCKWISE);
				pass->setDepthFunction(Ogre::CMPF_GREATER_EQUAL);
			}
			else
			{
				pass->setCullingMode(Ogre::CULL_CLOCKWISE);
				pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL);
			}
		}

		Camera shadowCam("ShadowCameraSetupCam", 0);
		shadowCam._notifyViewport(camera->getViewport());
		SceneManager* sm = mParentLight->_getManager();
		sm->getShadowCameraSetup()->getShadowCamera(sm,
			camera, camera->getViewport(), mParentLight, &shadowCam, 0);

		//Get the shadow camera position
		if (params->_findNamedConstantDefinition("shadowCamPos"))
		{
			params->setNamedConstant("shadowCamPos", shadowCam.getPosition());
		}
		if (params->_findNamedConstantDefinition("shadowFarClip"))
		{
			params->setNamedConstant("shadowFarClip", shadowCam.getFarClipDistance());
		}

	}
}
<|endoftext|>


<commit_before>#ifndef HEADERLIB_HDR_CORE_STD_HPP
#define HEADERLIB_HDR_CORE_STD_HPP
/*
 * hdrstd.hpp
 * A set of functions to denote function application, unify declarations and some
 * very broadly needed functionality. headerlib is not strongly typed, the functional
 * types are mostly denoted in comments above declarations. One day I might
 * think about giving type hints and doing optional type checking, but this
 * will probably be after the introduction of concepts.
 *
 *  Created on: 02.04.2016
 *      Author: andreas
 */

#include <cstdio>
#include <utility>
#include <type_traits>
#include "hdr/core/template_template_args_count.hpp"
#include "hdr/core/apply.hpp"
#include "hdr/core/convert.hpp"

/** This namespace holds all core utilities (and a few symbols more).
 *  Don't create any partial specializations where not explicitely noted.
 *
 *  The declatations in this namespace will not follow recommended principles,
 *  partly because the necessary structures aren't yet available or to offer
 *  slightly more optimized version. In case you are looking for examples,
 *  view headers outside of the core namespaces which operate fully within the
 *  invented functional type system.
 */
namespace hdr::std {

	template<typename F, typename... args>
	struct _Apply;
	template<typename F>
	struct _Apply<F> {
		using result = F;
	};
	template<typename F, typename FirstArg, typename... args>
	struct _Apply<F, FirstArg, args...> {
		using _applied = ApplySingle<F, FirstArg>;
		using result = typename _Apply<_applied, args...>::result;
	};
	/**
	 * (Partial) function application
	 */
	template<typename F, typename ...args>
	using Apply = typename _Apply<F, args...>::result;

	/**
	 * A function should be a templated struct with a member named result.
	 * An expression is a function that takes one template parameter but ignores it,
	 * it will/should generally be called with Void as the generic parameter. See them
	 * as lazy evaluated function calls, there is also a wrapper for exactly this.
	 */

	/**	The unit type. It CAN be inherited to signal the definition of a new type.
	 *  I'm not consistent about it, it's just here for convenience.
	 */
	struct Void {} __attribute__((packed));

	/**	Convenience to produce unevaluated, always failing static_asserts, e.g.
	 *	to create an error message in invalid partial specializations.
	 *  ```
	 *  template<typename T> struct CantInstantiate {
	 *		static_assert(_false<T>::value);
 	 *	};
	 *	```
	 *  Important, don't create any partial specializations.
	 */
	template<typename>
	struct _false: ::std::false_type {
	};
	template<auto value>
	struct _false_integral: ::std::false_type {
	};

	/**	Hides a type from immediate substitution in template using declarations.
	 *  Use it as Const<Value>.
	 *  It holds that Apply<Const<V>, T> === V for any (V, T)
	 */
	template<typename val>
	struct Const;
	template<typename Val, typename FirstArg>
	struct _apply<Const<Val>, FirstArg> {
		using type = Val;
	};

	/**	Constructor of the above as well as standalone function.
	 *  Ignores the second argument or constructs Const
	 *	(a -> b -> a)
	 */
	using fconst = TemplateFunction<Const>;

	/** Flips the order of two arguments
	 * 		(a -> b -> c) -> (b -> a -> c)
	 */
	template<typename F, typename B, typename A>
	struct Flip {
		using type = Apply<F, A, B>;
	};
	using flip   = TypeFunction<Flip>;

	/** Similar to fconst, but ignores its first argument
	 */
	using ignore = Apply<flip, fconst>;

	/** A function which will always return itself, infinitely
	 */
	struct VoidFunction;
	template<typename FirstArg>
	struct _apply<VoidFunction, FirstArg> {
		using type = VoidFunction;
	};

	/**	Type Definition of true, should be used as a parameter instead of bools.
	 */
	struct True : ::std::true_type , fconst {};
	/**	Type Definition of false, should be used as a parameter instead of bools.
	 */
	struct False : ::std::false_type , ignore {};

	/** Identity function for all Objects
	 *		(a -> a)
	 *	Can also be used as a functional form of apply.
	 *  We could also implement this as
	 *		template<typename T> using _id = T; using id = TemplateFunction<id>;
	 *	which would be neutral to the calling style but necessitate an additional
	 *  indirection through another type.
	 */
	struct id;
	template<typename FirstArg>
	struct _apply<id, FirstArg> {
		using type = FirstArg;
	};
	//Function Object of Apply
	using apply = id;

	/** Might make binary operators more intuitive, alternative to Apply. I haven't
	 *  felt the need to use it yet.
	 */
	template<typename aarg, typename op, typename barg>
	using Binary = Apply<op, aarg, barg>;
	using binary = Apply<flip, apply>;

	/**	Evaluates function composition, you might instead want to use
	 *		Apply<compose, F, G>
	 *	for clarity since it doesn't mix up Pures and Objects.
	 */
	template<typename F, typename G, typename Arg>
	struct Compose {
		using type = Apply<F, Apply<G, Arg>>;
	};
	/**	Binary operator for function composition
	 *		(a -> b) -> (b -> c) -> (a -> c)
	 */
	using compose = TypeFunction<Compose>;
	using c = compose;

	template<bool c, typename A, typename B>
	struct _Conditional {
		using result = A;
	};
	template<typename A, typename B>
	struct _Conditional<false, A, B> {
		using result = B;
	};
	/** Evaluates (c ? A : B) as a convenience type constructor.
	 */
	template<bool c, typename A, typename B>
	using Conditional = typename _Conditional<c, A, B>::result;
	template<bool b>
	using FromStdBool = Conditional;

	/** Specialize this for a custom bool operation
	 */
	template<typename T>
	struct Boolify { using type = FromStdBool<T::value>; };
	using boolify = TypeFunction<Boolify>;

	/** Functional Object of Conditional, use hdr::std::True and hdr::std::False
	 *  here instead of a bool. You could also use the truth type directly as
	 *  a function.
	 */
	using when_else = id;
	// Pretty ugly compare to when_else, just swap arguments yourself please
	using unless    = Apply<compose, flip, when_else>;

	/** This is really just apply but code might be easier to understand this way.
	 */
	template<typename ...Args>
	using When = Apply<when_else, Args...>;

	/** Type constexpr constructible from any arguments, could be useful.
	 */
	struct Sink {
		constexpr Sink(...){};
	};
	/** Same thing as the type as a function. If void is not an acceptable return
	 *  type for the context, I suggest comma operator, e.g.
	 *		(sink_args(args...), 0)
	 *	to return 0.
	 */
	constexpr void sink_args(...){ };

	/** Ideas for a type system, I haven't gotten very far here.
	 *  Specialize this struct for your own structures.
	 */
	template<typename Instance>
	struct Type {
		static_assert(_false<Instance>::value, "No type information available");
		using type = Void;
	};
	using typeof = TypeFunction<Type>;

	/** Void does not inherit from any type, hence it is its own type.
	 */
	template<>
	struct Type<Void>{
		using type = Void;
	};

	/** declare auto _ = Debug<Type>; to get your compiler to give you printable
	 *  information about Type.
	 */
	template<typename>
	struct Debug;

	/** This should be in its own file/namespace */
	template<typename O>
	struct Printer{
		static_assert(_false<O>::value, "No printer for target class defined");
		static void print();
	};
	template<>
	struct Printer<Void>{
		static void print(){};
	};
	template<>
	struct Printer<False>{
		static void print(){
			printf("false");
		}
	};
	template<>
	struct Printer<True>{
		static void print(){
			printf("true");
		}
	};

}
#endif //HEADERLIB_HDR_STD_HPP
<commit_msg>Improve syntax in core::std<commit_after>#ifndef HEADERLIB_HDR_CORE_STD_HPP
#define HEADERLIB_HDR_CORE_STD_HPP
/*
 * hdrstd.hpp
 * A set of functions to denote function application, unify declarations and some
 * very broadly needed functionality. headerlib is not strongly typed, the functional
 * types are mostly denoted in comments above declarations. One day I might
 * think about giving type hints and doing optional type checking, but this
 * will probably be after the introduction of concepts.
 *
 *  Created on: 02.04.2016
 *      Author: andreas
 */

#include <cstdio>
#include <utility>
#include <type_traits>
#include "hdr/core/template_template_args_count.hpp"
#include "hdr/core/apply.hpp"
#include "hdr/core/convert.hpp"

/** This namespace holds all core utilities (and a few symbols more).
 *  Don't create any partial specializations where not explicitely noted.
 *
 *  The declatations in this namespace will not follow recommended principles,
 *  partly because the necessary structures aren't yet available or to offer
 *  slightly more optimized version. In case you are looking for examples,
 *  view headers outside of the core namespaces which operate fully within the
 *  invented functional type system.
 */
namespace hdr::std {

	template<typename F, typename... args>
	struct _Apply;
	template<typename F>
	struct _Apply<F> {
		using result = F;
	};
	template<typename F, typename FirstArg, typename... args>
	struct _Apply<F, FirstArg, args...> {
		using _applied = ApplySingle<F, FirstArg>;
		using result = typename _Apply<_applied, args...>::result;
	};
	/**
	 * (Partial) function application
	 */
	template<typename F, typename ...args>
	using Apply = typename _Apply<F, args...>::result;

	/**
	 * A function should be a templated struct with a member named result.
	 * An expression is a function that takes one template parameter but ignores it,
	 * it will/should generally be called with Void as the generic parameter. See them
	 * as lazy evaluated function calls, there is also a wrapper for exactly this.
	 */

	/**	The unit type. It CAN be inherited to signal the definition of a new type.
	 *  I'm not consistent about it, it's just here for convenience.
	 */
	struct Void {} __attribute__((packed));

	/**	Convenience to produce unevaluated, always failing static_asserts, e.g.
	 *	to create an error message in invalid partial specializations.
	 *  ```
	 *  template<typename T> struct CantInstantiate {
	 *		static_assert(_false<T>::value);
 	 *	};
	 *	```
	 *  Important, don't create any partial specializations.
	 */
	template<typename>
	struct _false: ::std::false_type {
	};
	template<auto value>
	struct _false_integral: ::std::false_type {
	};

	/**	Hides a type from immediate substitution in template using declarations.
	 *  Use it as Const<Value>.
	 *  It holds that Apply<Const<V>, T> === V for any (V, T)
	 */
	template<typename val>
	struct Const;
	template<typename Val, typename FirstArg>
	struct _apply<Const<Val>, FirstArg> {
		using type = Val;
	};

	/**	Constructor of the above as well as standalone function.
	 *  Ignores the second argument or constructs Const
	 *	(a -> b -> a)
	 */
	using fconst = TemplateFunction<Const>;

	/** Flips the order of two arguments
	 * 		(a -> b -> c) -> (b -> a -> c)
	 */
	template<typename F, typename B, typename A>
	using _flip = Apply<F, A, B>;
	using flip   = TemplateFunction<_flip>;

	/** Similar to fconst, but ignores its first argument
	 */
	using ignore = Apply<flip, fconst>;

	/** A function which will always return itself, infinitely
	 */
	struct VoidFunction;
	template<typename FirstArg>
	struct _apply<VoidFunction, FirstArg> {
		using type = VoidFunction;
	};

	/**	Type Definition of true, should be used as a parameter instead of bools.
	 */
	struct True : ::std::true_type , fconst {};
	/**	Type Definition of false, should be used as a parameter instead of bools.
	 */
	struct False : ::std::false_type , ignore {};

	/** Identity function for all Objects
	 *		(a -> a)
	 *	Can also be used as a functional form of apply.
	 *  We could also implement this as
	 *		template<typename T> using _id = T; using id = TemplateFunction<id>;
	 *	which would be neutral to the calling style but necessitate an additional
	 *  indirection through another type.
	 */
	struct id;
	template<typename FirstArg>
	struct _apply<id, FirstArg> {
		using type = FirstArg;
	};
	//Function Object of Apply
	using apply = id;

	/** Might make binary operators more intuitive, alternative to Apply. I haven't
	 *  felt the need to use it yet.
	 */
	template<typename aarg, typename op, typename barg>
	using Binary = Apply<op, aarg, barg>;
	using binary = Apply<flip, apply>;

	/**	Evaluates function composition, you might instead want to use
	 *		Apply<compose, F, G>
	 *	for clarity since it doesn't mix up Pures and Objects.
	 */
	template<typename F, typename G, typename Arg>
	using _compose = Apply<F, Apply<G, Arg>>;
	/**	Binary operator for function composition
	 *		(a -> b) -> (b -> c) -> (a -> c)
	 */
	using compose = TemplateFunction<_compose>;
	using c = compose;

	template<bool c, typename A, typename B>
	struct _Conditional {
		using result = A;
	};
	template<typename A, typename B>
	struct _Conditional<false, A, B> {
		using result = B;
	};
	/** Evaluates (c ? A : B) as a convenience type constructor.
	 */
	template<bool c, typename A, typename B>
	using Conditional = typename _Conditional<c, A, B>::result;
	template<bool b>
	using FromStdBool = Conditional;

	/** Specialize this for a custom bool operation
	 */
	template<typename T>
	struct Boolify { using type = FromStdBool<T::value>; };
	using boolify = TypeFunction<Boolify>;

	/** Functional Object of Conditional, use hdr::std::True and hdr::std::False
	 *  here instead of a bool. You could also use the truth type directly as
	 *  a function.
	 */
	using when_else = id;
	// Pretty ugly compare to when_else, just swap arguments yourself please
	using unless    = Apply<compose, flip, when_else>;

	/** This is really just apply but code might be easier to understand this way.
	 */
	template<typename ...Args>
	using When = Apply<when_else, Args...>;

	/** Type constexpr constructible from any arguments, could be useful.
	 */
	struct Sink {
		constexpr Sink(...){};
	};
	/** Same thing as the type as a function. If void is not an acceptable return
	 *  type for the context, I suggest comma operator, e.g.
	 *		(sink_args(args...), 0)
	 *	to return 0.
	 */
	constexpr void sink_args(...){ };

	/** Ideas for a type system, I haven't gotten very far here.
	 *  Specialize this struct for your own structures.
	 */
	template<typename Instance>
	struct Type {
		static_assert(_false<Instance>::value, "No type information available");
		using type = Void;
	};
	using typeof = TypeFunction<Type>;

	/** Void does not inherit from any type, hence it is its own type.
	 */
	template<>
	struct Type<Void>{
		using type = Void;
	};

	/** declare auto _ = Debug<Type>; to get your compiler to give you printable
	 *  information about Type.
	 */
	template<typename>
	struct Debug;

	/** This should be in its own file/namespace */
	template<typename O>
	struct Printer{
		static_assert(_false<O>::value, "No printer for target class defined");
		static void print();
	};
	template<>
	struct Printer<Void>{
		static void print(){};
	};
	template<>
	struct Printer<False>{
		static void print(){
			printf("false");
		}
	};
	template<>
	struct Printer<True>{
		static void print(){
			printf("true");
		}
	};

}
#endif //HEADERLIB_HDR_STD_HPP
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "GameManager.h"
#include "GameRoom.h"
#include "Game.h"
#include "Player.h"
#include "ClientManager.h"
#include "ClientSession.h"
#include "Scheduler.h"
#include "Config.h"

GameManager* GGameManager = nullptr;

GameRoom* GameManager::CreateRoom()
{
	if (m_MakeRoomNum == 0)
		LowTick();

	GameRoom* room = new GameRoom(++m_MakeRoomNum);

	if (m_RoomList[m_MakeRoomNum] != nullptr)
		delete m_RoomList[m_MakeRoomNum];

	m_RoomList[m_MakeRoomNum] = room;

	return room;
}

void GameManager::DeleteRoom(int roomId)
{
	for (auto& iter = m_RoomList.begin(); iter != m_RoomList.end(); ++iter)
	{
		if (iter->first == roomId)
		{
			delete iter->second;
			m_RoomList.erase(iter);
			break;
		}
	}
	printf(" - Destroy %d Room ! \n", roomId);
}

GameRoom* GameManager::SearchRoom(int roomId)
{
	for (auto& room : m_RoomList)
	{
		if (room.first == roomId)
		{
			return room.second;
		}
	}
	printf(" - Room Search Failed ! \n");
	return nullptr;
}

int GameManager::SearchEmptyRoom()
{
	for (auto& room : m_RoomList)
	{
		if (room.second->IsJoinAble())
		{
			return room.second->GetRoomID();
		}
	}
	printf(" - No Room ! \n");
	return -1;
}

void GameManager::JoinRoom(int playerId, int roomId)
{
	m_RoomList[roomId]->JoinPlayer(playerId);
}

void GameManager::OutRoom(int playerId, int roomId)
{
	m_RoomList[roomId]->OutPlayer(playerId);

	if (m_RoomList[roomId]->GetPlayerListNum() == 0)
	{
		DeleteRoom(roomId);
	}
}

void GameManager::PlayerOut(int playerId)
{
	for (auto& game : m_GameList)
	{
		for (auto& player : game.second->GetPlayerList())
		{
			if (player.first == playerId)
				game.second->PlayerOut(playerId);
		}
	}
}

void GameManager::CreateGame(int roomId)
{
	Game* game = new Game(roomId);

	if (m_GameList[roomId] != nullptr)
		delete m_GameList[roomId];

	m_GameList[roomId] = game;
	game->SetPlayerList(m_RoomList[roomId]->GetPlayerList());
}

void GameManager::DeleteGame(int gameId)
{
	for (auto& iter = m_GameList.begin(); iter != m_GameList.end(); ++iter)
	{
		if (iter->first == gameId)
		{
			delete iter->second;
			m_GameList.erase(iter);
			break;
		}
	}
	printf(" - Destroy %d Game ! \n", gameId);
}

///////////////////////////////////////////////////////////////////////////
/*

*/
///////////////////////////////////////////////////////////////////////////
void GameManager::InitPhyWorld()
{
	b2Vec2 gravity(0.0f, 0.0f);
	m_World = new b2World(gravity);

	m_World->SetAllowSleeping(true);
	m_World->SetContinuousPhysics(true);
}
void GameManager::DeletePhyWorld()
{
	delete m_World;
}

///////////////////////////////////////////////////////////////////////////
/*
	 Ӹ
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::Tick(float dt)
{
	m_World->Step(dt, 8, 3);

	for (auto& room : m_RoomList)
	{
		if (room.second->IsAllReady())
		{
			//   !;
			printf(" - All Player is Ready ! :: %d Room is Game Start !! \n", room.first);
			CreateGame(room.first);
			room.second->InitReady();
		}
	}

	for (auto& game : m_GameList)
	{
		if (!game.second->GetIsStart())
			continue;

		for (auto& player : game.second->GetPlayerList())
		{
			auto client = GClientManager->GetClient(player.first);
			auto unit = player.second->GetMyHero();
			client->SendUnitInfo(unit->GetUnitID(), unit->GetUnitType(), unit->GetCurrentPos());
		}
	}
}

///////////////////////////////////////////////////////////////////////////
/*
	MANAGER_UPDATE_INTERVAL ֱ
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::LowTick()
{

	CallFuncAfter(MANAGER_UPDATE_INTERVAL, this, &GameManager::LowTick);
}
<commit_msg>[S] PlayerOut 문제 수정<commit_after>#include "stdafx.h"
#include "GameManager.h"
#include "GameRoom.h"
#include "Game.h"
#include "Player.h"
#include "ClientManager.h"
#include "ClientSession.h"
#include "Scheduler.h"
#include "Config.h"

GameManager* GGameManager = nullptr;

GameRoom* GameManager::CreateRoom()
{
	if (m_MakeRoomNum == 0)
		LowTick();

	GameRoom* room = new GameRoom(++m_MakeRoomNum);

	if (m_RoomList[m_MakeRoomNum] != nullptr)
		delete m_RoomList[m_MakeRoomNum];

	m_RoomList[m_MakeRoomNum] = room;

	return room;
}

void GameManager::DeleteRoom(int roomId)
{
	for (auto& iter = m_RoomList.begin(); iter != m_RoomList.end(); ++iter)
	{
		if (iter->first == roomId)
		{
			delete iter->second;
			m_RoomList.erase(iter);
			break;
		}
	}
	printf(" - Destroy %d Room ! \n", roomId);
}

GameRoom* GameManager::SearchRoom(int roomId)
{
	for (auto& room : m_RoomList)
	{
		if (room.first == roomId)
		{
			return room.second;
		}
	}
	printf(" - Room Search Failed ! \n");
	return nullptr;
}

int GameManager::SearchEmptyRoom()
{
	for (auto& room : m_RoomList)
	{
		if (room.second->IsJoinAble())
		{
			return room.second->GetRoomID();
		}
	}
	printf(" - No Room ! \n");
	return -1;
}

void GameManager::JoinRoom(int playerId, int roomId)
{
	m_RoomList[roomId]->JoinPlayer(playerId);
}

void GameManager::OutRoom(int playerId, int roomId)
{
	m_RoomList[roomId]->OutPlayer(playerId);

	if (m_RoomList[roomId]->GetPlayerListNum() == 0)
	{
		DeleteRoom(roomId);
	}
}

void GameManager::PlayerOut(int playerId)
{
	for (auto& game : m_GameList)
	{
		for (auto& player : game.second->GetPlayerList())
		{
			if (player.first == playerId)
			{
				game.second->PlayerOut(playerId);
				break;
			}
		}
	}
}

void GameManager::CreateGame(int roomId)
{
	Game* game = new Game(roomId);

	if (m_GameList[roomId] != nullptr)
		delete m_GameList[roomId];

	m_GameList[roomId] = game;
	game->SetPlayerList(m_RoomList[roomId]->GetPlayerList());
}

void GameManager::DeleteGame(int gameId)
{
	for (auto& iter = m_GameList.begin(); iter != m_GameList.end(); ++iter)
	{
		if (iter->first == gameId)
		{
			delete iter->second;
			m_GameList.erase(iter);
			break;
		}
	}
	printf(" - Destroy %d Game ! \n", gameId);
}

///////////////////////////////////////////////////////////////////////////
/*

*/
///////////////////////////////////////////////////////////////////////////
void GameManager::InitPhyWorld()
{
	b2Vec2 gravity(0.0f, 0.0f);
	m_World = new b2World(gravity);

	m_World->SetAllowSleeping(true);
	m_World->SetContinuousPhysics(true);
}
void GameManager::DeletePhyWorld()
{
	delete m_World;
}

///////////////////////////////////////////////////////////////////////////
/*
	 Ӹ
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::Tick(float dt)
{
	m_World->Step(dt, 8, 3);

	for (auto& room : m_RoomList)
	{
		if (room.second->IsAllReady())
		{
			//   !;
			printf(" - All Player is Ready ! :: %d Room is Game Start !! \n", room.first);
			CreateGame(room.first);
			room.second->InitReady();
		}
	}

	for (auto& game : m_GameList)
	{
		if (!game.second->GetIsStart())
			continue;

		for (auto& player : game.second->GetPlayerList())
		{
			auto client = GClientManager->GetClient(player.first);
			auto unit = player.second->GetMyHero();
			client->SendUnitInfo(unit->GetUnitID(), unit->GetUnitType(), unit->GetCurrentPos());
		}
	}
}

///////////////////////////////////////////////////////////////////////////
/*
	MANAGER_UPDATE_INTERVAL ֱ
*/
///////////////////////////////////////////////////////////////////////////
void GameManager::LowTick()
{

	CallFuncAfter(MANAGER_UPDATE_INTERVAL, this, &GameManager::LowTick);
}
<|endoftext|>


<commit_before>#include "temperaturescreen.h"
#include "ui_temperaturescreen.h"
#include "temperatuur.h"

temperaturescreen::temperaturescreen(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::temperaturescreen)
{
    ui->setupUi(this);

    ui->dial->setValue(Ingesteldetemperatuur);

    QTimer *timer = new QTimer(this); // this form
    connect(
                timer,
                SIGNAL(timeout()),  // SLOT happends when there is a SIGNAL, timeout is emitted when the timer times out
                this,
                SLOT(tempSensor())    // shows time again, after a timeout, this makes it realtime
            ); //

    timer->start();

}

temperaturescreen::~temperaturescreen()
{
    Ingesteldetemperatuur = ui->dial->value();
    delete ui;
}

void temperaturescreen::tempSensor(){

    test += 1;
    if(test >= 1000){
        temp += 1;
            if(temp > 30){
                temp = 0;
            }
        LcdNumber_2_Display(temp);
        test = 0;
    }
}

void temperaturescreen::LcdNumber_2_Display(int i){
    ui->lcdNumber_2->display(i);
}

void temperaturescreen::on_pushButton_clicked(){
    //this->hide();
    this->~temperaturescreen();
    ScreenAfterLogin ScreenAfterLogin;
    ScreenAfterLogin.setModal(true); // shows ScreenAfterLogin screen
    ScreenAfterLogin.exec();
}
<commit_msg>Update temperaturescreen.cpp<commit_after>#include "temperaturescreen.h"
#include "ui_temperaturescreen.h"
#include "temperatuur.h"

temperaturescreen::temperaturescreen(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::temperaturescreen)
{
    ui->setupUi(this);

    QTimer *Deadtimer = new QTimer(this);
	Deadtimer->setInterval(15*1000);
	Deadtimer->setSingleShot(true);
	connect(Deadtimer,SIGNAL(timeout()),SLOT(LogOut()));
	Deadtimer->start();
	deadtimer=Deadtimer;

    ui->dial->setValue(Ingesteldetemperatuur);

    QTimer *timer = new QTimer(this); // this form
    connect(
                timer,
                SIGNAL(timeout()),  // SLOT happends when there is a SIGNAL, timeout is emitted when the timer times out
                this,
                SLOT(tempSensor())    // shows time again, after a timeout, this makes it realtime
            ); //

    timer->start();

}

temperaturescreen::~temperaturescreen()
{
    Ingesteldetemperatuur = ui->dial->value();
    delete ui;
}

void  temperaturescreen::resettimer(){
    deadtimer->stop();
    deadtimer->start();
}

void temperaturescreen::tempSensor(){

    resettemp += 1;
    if(resettemp >= 1000){
        LcdNumber_2_Display(temperature);
        resettemp = 0;
    }
}

void temperaturescreen::LcdNumber_2_Display(int i){
    ui->lcdNumber_2->display(i);
}

void temperaturescreen::on_pushButton_clicked(){
    //this->hide();
    this->~temperaturescreen();
    ScreenAfterLogin ScreenAfterLogin;
    ScreenAfterLogin.setModal(true); // shows ScreenAfterLogin screen
    ScreenAfterLogin.exec();
}
<|endoftext|>


<commit_before>#ifndef CPPTOOL_PROTOBUF_OUTPUT_H
#define CPPTOOL_PROTOBUF_OUTPUT_H

#include <cstdio>
#include <type_traits>

#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/message.h>

namespace ct {
	class ProtobufOutput {
		google::protobuf::io::FileOutputStream backendStream;
		google::protobuf::io::CodedOutputStream output;
	public:
		ProtobufOutput(std::FILE *file);

		template<typename MessageLite>
		void writeMessage(typename std::remove_reference<MessageLite>::type &msg);
	private:
		static int fileToDescriptor(std::FILE *file);
	};

	template<typename MessageLite>
	void ProtobufOutput::writeMessage(typename std::remove_reference<MessageLite>::type &msg) {
		output.WriteVarint32(msg.ByteSize());
		msg.SerializeToCodedStream(&output);
		//TODO: validate return bool
#ifdef CPPTOOL_ENABLE_PROTOBUF_DUMP
		msg.PrintDebugString();
#endif //CPPTOOL_ENABLE_PROTOBUF_DUMP
	}
}

#endif //CPPTOOL_PROTOBUF_OUTPUT_H<commit_msg>Add abort if protobuf write fails<commit_after>#ifndef CPPTOOL_PROTOBUF_OUTPUT_H
#define CPPTOOL_PROTOBUF_OUTPUT_H

#include <cstdio>
#include <type_traits>

#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/message.h>

namespace ct {
	class ProtobufOutput {
		google::protobuf::io::FileOutputStream backendStream;
		google::protobuf::io::CodedOutputStream output;
	public:
		ProtobufOutput(std::FILE *file);

		template<typename MessageLite>
		void writeMessage(typename std::remove_reference<MessageLite>::type &msg);
	private:
		static int fileToDescriptor(std::FILE *file);
	};

	template<typename MessageLite>
	void ProtobufOutput::writeMessage(typename std::remove_reference<MessageLite>::type &msg) {
		output.WriteVarint32(msg.ByteSize());
		if (!msg.SerializeToCodedStream(&output)) {
			::abort();
		}
#ifdef CPPTOOL_ENABLE_PROTOBUF_DUMP
		msg.PrintDebugString();
#endif //CPPTOOL_ENABLE_PROTOBUF_DUMP
	}
}

#endif //CPPTOOL_PROTOBUF_OUTPUT_H<|endoftext|>


<commit_before>/*
        AtlasServer.cpp
        ----------------
        begin           : 1999.11.29
        copyright       : (C) 1999 by John Barrett (ZW)
        email           : jbarrett@box100.com
*/

#include "AtlasServer.h"

// start listening for connections on an established socket
AServer::AServer(ASocket* listener)
{
	lsock = listener;
	slsock = lsock->getSock();

	FD_ZERO(&fdread);
	FD_ZERO(&fdsend);
	FD_ZERO(&fderrs);

	FD_SET(slsock, &fdread);
	FD_SET(slsock, &fderrs);
}

// poll returns true if connections to accept
// processes all inbound data and sends to client objects
int AServer::poll()
{
	return poll(100);
}

int AServer::poll(long usec)
{
	int 		i;
	struct timeval	tm;

	tm.tv_sec = 0;
	tm.tv_usec = usec;

	fd_set	xread = fdread;
	fd_set	xsend = fdsend;
	fd_set	xerrs = fderrs;

	select(0,&xread,&xsend,&xerrs,&tm);

	for (i=0; i<FD_SETSIZE; i++)
	if (i != slsock)
	{
		if (FD_ISSET(i,&xread)) csock[i]->canRead();
		if (FD_ISSET(i,&xsend)) csock[i]->canSend();
		if (FD_ISSET(i,&xerrs)) csock[i]->gotErrs();
	}
	if (FD_ISSET(slsock, &xread)) return 1;
	return 0;
}

// retrieve a new socket connection
ASocket* AServer::accept()
{
	return lsock->accept();
}

// register a client for read data events
int AServer::addClient(AClient* client)
{
	SOCKET sock = client->getSock();

	csock[sock] = client;
	FD_SET(sock,&fdread);
	FD_SET(sock,&fderrs);
	return 1;
}

// remove a client from the read event list
int AServer::delClient(AClient* client)
{
	SOCKET sock = client->getSock();

	if (csock[sock] == NULL) return 0;
	csock[sock] = NULL;
	FD_CLR(sock,&fdread);
	FD_CLR(sock,&fdsend);
	FD_CLR(sock,&fderrs);
	return 1;
}

// add a client from the send event list
int AServer::addClientSend(AClient* client)
{
	SOCKET sock = client->getSock();

	if (csock[sock] == NULL) return 0;
	FD_SET(sock,&fdsend);
	return 1;
}

// remove a client from the send event list
int AServer::delClientSend(AClient* client)
{
	SOCKET sock = client->getSock();

	if (csock[sock] == NULL) return 0;
	FD_CLR(sock,&fdsend);
	return 1;
}

<commit_msg>AtlasChat client and server working !!! YAAAAAA<commit_after>/*
        AtlasServer.cpp
        ----------------
        begin           : 1999.11.29
        copyright       : (C) 1999 by John Barrett (ZW)
        email           : jbarrett@box100.com
*/

#include "AtlasServer.h"

// start listening for connections on an established socket
AServer::AServer(ASocket* listener)
{
	lsock = listener;
	slsock = lsock->getSock();

	FD_ZERO(&fdread);
	FD_ZERO(&fdsend);
	FD_ZERO(&fderrs);

	FD_SET(slsock, &fdread);
	FD_SET(slsock, &fderrs);
}

// poll returns true if connections to accept
// processes all inbound data and sends to client objects
int AServer::poll()
{
	return poll(100);
}

int AServer::poll(long usec)
{
	int 		i;
	struct timeval	tm;

	tm.tv_sec = 0;
	tm.tv_usec = usec;

	fd_set	xread = fdread;
	fd_set	xsend = fdsend;
	fd_set	xerrs = fderrs;

	select(0,&xread,&xsend,&xerrs,&tm);

	for (i=0; i<FD_SETSIZE; i++)
	if (i != slsock)
	{
		if (FD_ISSET(i,&xread)) csock[i]->canRead();
		if (FD_ISSET(i,&xsend)) csock[i]->canSend();
		if (FD_ISSET(i,&xerrs)) csock[i]->gotErrs();
	}
	if (FD_ISSET(slsock, &xread)) return 1;
	return 0;
}

// retrieve a new socket connection
ASocket* AServer::accept()
{
	return lsock->accept();
}

// register a client for read data events
int AServer::addClient(AClient* client)
{
	SOCKET sock = client->getSock();

	csock[sock] = client;
	FD_SET(sock,&fdread);
	FD_SET(sock,&fderrs);
	return 1;
}

// remove a client from the read event list
int AServer::delClient(AClient* client)
{
	SOCKET sock = client->getSock();

	if (csock[sock] == NULL) return 0;
	csock[sock] = NULL;
	FD_CLR(sock,&fdread);
	FD_CLR(sock,&fdsend);
	FD_CLR(sock,&fderrs);
	return 1;
}

// add a client to the send event list
int AServer::addClientSend(AClient* client)
{
	SOCKET sock = client->getSock();

	if (csock[sock] == NULL) return 0;
	FD_SET(sock,&fdsend);
	return 1;
}

// remove a client from the send event list
int AServer::delClientSend(AClient* client)
{
	SOCKET sock = client->getSock();

	if (csock[sock] == NULL) return 0;
	FD_CLR(sock,&fdsend);
	return 1;
}

<|endoftext|>