<commit_before>#include <ghost.h>
#include <ghost_util.h>
#include <ghost_vec.h>
#include <cmath>
#include <cstdio>
#include "ghost_complex.h"
#include <omp.h>

template <typename v_t> void ghost_normalizeVector_tmpl(ghost_vec_t *vec)
{
	v_t s;
	ghost_vec_dotprod_tmpl<v_t>(vec,vec,&s);
	s = (v_t)sqrt(s);
	s = (v_t)(((v_t)1.)/s);
	vec->scale(vec,&s);

#ifdef OPENCL
	vec->CLupload(vec);
#endif
#ifdef CUDA
	vec->CUupload(vec);
#endif
}

template <typename v_t> void ghost_vec_dotprod_tmpl(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ // the parallelization is done manually because reduction does not work with ghost_complex numbers
	if (vec->traits->nrows != vec2->traits->nrows) {
		WARNING_LOG("The input vectors of the dot product have different numbers of rows");
	}
	if (vec->traits->nvecs != vec2->traits->nvecs) {
		WARNING_LOG("The input vectors of the dot product have different numbers of columns");
	}
	ghost_vidx_t i,v;
	ghost_vidx_t nr = MIN(vec->traits->nrows,vec2->traits->nrows);

	int nthreads;
#pragma omp parallel
	nthreads = ghost_ompGetNumThreads();

	for (v=0; v<MIN(vec->traits->nvecs,vec2->traits->nvecs); v++) {
		v_t sum = 0;
		v_t partsums[nthreads];
		for (i=0; i<nthreads; i++) partsums[i] = (v_t)0.;

#pragma omp parallel for
		for (i=0; i<nr; i++) {
			partsums[ghost_ompGetThreadNum()] +=
				((v_t *)(vec->val))[i+vec->traits->nrowspadded*v]*((v_t *)(vec2->val))[i+vec->traits->nrowspadded*v];
		}

		for (i=0; i<nthreads; i++) sum += partsums[i];

		((v_t *)res)[v] = sum;
	}

}

template <typename v_t> void ghost_vec_vaxpy_tmpl(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{
	ghost_vidx_t i,v;
	v_t *s = (v_t *)scale;
	ghost_vidx_t nr = MIN(vec->traits->nrows,vec2->traits->nrows);

	for (v=0; v<MIN(vec->traits->nvecs,vec2->traits->nvecs); v++) {
#pragma omp parallel for
		for (i=0; i<nr; i++) {
			((v_t *)(vec->val))[i+vec->traits->nrowspadded*v] += ((v_t *)(vec2->val))[i+vec->traits->nrowspadded*v] * s[v];
		}
	}
}

template <typename v_t> void ghost_vec_vaxpby_tmpl(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b_)
{
	ghost_vidx_t i,v;
	v_t *s = (v_t *)scale;
	v_t *b = (v_t *)b_;
	ghost_vidx_t nr = MIN(vec->traits->nrows,vec2->traits->nrows);

	for (v=0; v<MIN(vec->traits->nvecs,vec2->traits->nvecs); v++) {
#pragma omp parallel for
		for (i=0; i<nr; i++) {
			((v_t *)(vec->val))[i+vec->traits->nrowspadded*v] = ((v_t *)(vec2->val))[i+vec->traits->nrowspadded*v] * s[v] +
				((v_t *)(vec->val))[i+vec->traits->nrowspadded*v] * b[v];
		}
	}
}

template<typename v_t> void ghost_vec_vscale_tmpl(ghost_vec_t *vec, void *scale)
{
	ghost_vidx_t i,v;
	v_t *s = (v_t *)scale;

	for (v=0; v<vec->traits->nvecs; v++) {
#pragma omp parallel for
		for (i=0; i<vec->traits->nrows; i++) {
			((v_t *)(vec->val))[i] *= s[v];
		}
	}
}

template <typename v_t> void ghost_vec_fromRand_tmpl(ghost_vec_t *vec)
{
	vec_malloc(vec);
	DEBUG_LOG(1,"Filling vector with random values");
	size_t sizeofdt = ghost_sizeofDataType(vec->traits->datatype);

	vec->val = ghost_malloc(vec->traits->nvecs*vec->traits->nrowspadded*sizeofdt);
	int i,v;

	// TODO fuse loops but preserve randomness

	if (vec->traits->nvecs > 1) {
#pragma omp parallel for schedule(runtime) private(i)
		for (v=0; v<vec->traits->nvecs; v++) {
			for (i=0; i<vec->traits->nrows; i++) {
				((v_t *)(vec->val))[v*vec->traits->nrowspadded+i] = (v_t)0;
			}
		}
	} else {
#pragma omp parallel for schedule(runtime)
		for (i=0; i<vec->traits->nrows; i++) {
			((v_t *)(vec->val))[i] = (v_t)0;
		}
	}

	for (v=0; v<vec->traits->nvecs; v++) {
		for (i=0; i<vec->traits->nrows; i++) {
			((v_t *)(vec->val))[v*vec->traits->nrowspadded+i] = (v_t)(rand()*1./RAND_MAX); // TODO imag
		}
	}
	vec->upload(vec);

}

extern "C" void d_ghost_normalizeVector(ghost_vec_t *vec)
{ return ghost_normalizeVector_tmpl< double >(vec); }

extern "C" void s_ghost_normalizeVector(ghost_vec_t *vec)
{ return ghost_normalizeVector_tmpl< float >(vec); }

extern "C" void z_ghost_normalizeVector(ghost_vec_t *vec)
{ return ghost_normalizeVector_tmpl< ghost_complex<double> >(vec); }

extern "C" void c_ghost_normalizeVector(ghost_vec_t *vec)
{ return ghost_normalizeVector_tmpl< ghost_complex<float> >(vec); }

extern "C" void d_ghost_vec_dotprod(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ return ghost_vec_dotprod_tmpl< double >(vec,vec2,res); }

extern "C" void s_ghost_vec_dotprod(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ return ghost_vec_dotprod_tmpl< float >(vec,vec2,res); }

extern "C" void z_ghost_vec_dotprod(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ return ghost_vec_dotprod_tmpl< ghost_complex<double> >(vec,vec2,res); }

extern "C" void c_ghost_vec_dotprod(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ return ghost_vec_dotprod_tmpl< ghost_complex<float> >(vec,vec2,res); }

extern "C" void d_ghost_vec_vscale(ghost_vec_t *vec, void *scale)
{ return ghost_vec_vscale_tmpl< double >(vec, scale); }

extern "C" void s_ghost_vec_vscale(ghost_vec_t *vec, void *scale)
{ return ghost_vec_vscale_tmpl< float  >(vec, scale); }

extern "C" void z_ghost_vec_vscale(ghost_vec_t *vec, void *scale)
{ return ghost_vec_vscale_tmpl< ghost_complex<double> >(vec, scale); }

extern "C" void c_ghost_vec_vscale(ghost_vec_t *vec, void *scale)
{ return ghost_vec_vscale_tmpl< ghost_complex<float> >(vec, scale); }

extern "C" void d_ghost_vec_vaxpy(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{ return ghost_vec_vaxpy_tmpl< double >(vec, vec2, scale); }

extern "C" void s_ghost_vec_vaxpy(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{ return ghost_vec_vaxpy_tmpl< float >(vec, vec2, scale); }

extern "C" void z_ghost_vec_vaxpy(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{ return ghost_vec_vaxpy_tmpl< ghost_complex<double> >(vec, vec2, scale); }

extern "C" void c_ghost_vec_vaxpy(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{ return ghost_vec_vaxpy_tmpl< ghost_complex<float> >(vec, vec2, scale); }

extern "C" void d_ghost_vec_vaxpby(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b)
{ return ghost_vec_vaxpby_tmpl< double >(vec, vec2, scale, b); }

extern "C" void s_ghost_vec_vaxpby(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b)
{ return ghost_vec_vaxpby_tmpl< float >(vec, vec2, scale, b); }

extern "C" void z_ghost_vec_vaxpby(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b)
{ return ghost_vec_vaxpby_tmpl< ghost_complex<double> >(vec, vec2, scale, b); }

extern "C" void c_ghost_vec_vaxpby(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b)
{ return ghost_vec_vaxpby_tmpl< ghost_complex<float> >(vec, vec2, scale, b); }

extern "C" void d_ghost_vec_fromRand(ghost_vec_t *vec)
{ return ghost_vec_fromRand_tmpl< double >(vec); }

extern "C" void s_ghost_vec_fromRand(ghost_vec_t *vec)
{ return ghost_vec_fromRand_tmpl< float >(vec); }

extern "C" void z_ghost_vec_fromRand(ghost_vec_t *vec)
{ return ghost_vec_fromRand_tmpl< ghost_complex<double> >(vec); }

extern "C" void c_ghost_vec_fromRand(ghost_vec_t *vec)
{ return ghost_vec_fromRand_tmpl< ghost_complex<float> >(vec); }

<commit_msg>bugfix in vec_vscale (thanks to Jonas)<commit_after>#include <ghost.h>
#include <ghost_util.h>
#include <ghost_vec.h>
#include <cmath>
#include <cstdio>
#include "ghost_complex.h"
#include <omp.h>

template <typename v_t> void ghost_normalizeVector_tmpl(ghost_vec_t *vec)
{
	v_t s;
	ghost_vec_dotprod_tmpl<v_t>(vec,vec,&s);
	s = (v_t)sqrt(s);
	s = (v_t)(((v_t)1.)/s);
	vec->scale(vec,&s);

#ifdef OPENCL
	vec->CLupload(vec);
#endif
#ifdef CUDA
	vec->CUupload(vec);
#endif
}

template <typename v_t> void ghost_vec_dotprod_tmpl(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ // the parallelization is done manually because reduction does not work with ghost_complex numbers
	if (vec->traits->nrows != vec2->traits->nrows) {
		WARNING_LOG("The input vectors of the dot product have different numbers of rows");
	}
	if (vec->traits->nvecs != vec2->traits->nvecs) {
		WARNING_LOG("The input vectors of the dot product have different numbers of columns");
	}
	ghost_vidx_t i,v;
	ghost_vidx_t nr = MIN(vec->traits->nrows,vec2->traits->nrows);

	int nthreads;
#pragma omp parallel
	nthreads = ghost_ompGetNumThreads();

	for (v=0; v<MIN(vec->traits->nvecs,vec2->traits->nvecs); v++) {
		v_t sum = 0;
		v_t partsums[nthreads];
		for (i=0; i<nthreads; i++) partsums[i] = (v_t)0.;

#pragma omp parallel for
		for (i=0; i<nr; i++) {
			partsums[ghost_ompGetThreadNum()] +=
				((v_t *)(vec->val))[i+vec->traits->nrowspadded*v]*((v_t *)(vec2->val))[i+vec->traits->nrowspadded*v];
		}

		for (i=0; i<nthreads; i++) sum += partsums[i];

		((v_t *)res)[v] = sum;
	}

}

template <typename v_t> void ghost_vec_vaxpy_tmpl(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{
	ghost_vidx_t i,v;
	v_t *s = (v_t *)scale;
	ghost_vidx_t nr = MIN(vec->traits->nrows,vec2->traits->nrows);

	for (v=0; v<MIN(vec->traits->nvecs,vec2->traits->nvecs); v++) {
#pragma omp parallel for
		for (i=0; i<nr; i++) {
			((v_t *)(vec->val))[i+vec->traits->nrowspadded*v] += ((v_t *)(vec2->val))[i+vec->traits->nrowspadded*v] * s[v];
		}
	}
}

template <typename v_t> void ghost_vec_vaxpby_tmpl(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b_)
{
	ghost_vidx_t i,v;
	v_t *s = (v_t *)scale;
	v_t *b = (v_t *)b_;
	ghost_vidx_t nr = MIN(vec->traits->nrows,vec2->traits->nrows);

	for (v=0; v<MIN(vec->traits->nvecs,vec2->traits->nvecs); v++) {
#pragma omp parallel for
		for (i=0; i<nr; i++) {
			((v_t *)(vec->val))[i+vec->traits->nrowspadded*v] = ((v_t *)(vec2->val))[i+vec->traits->nrowspadded*v] * s[v] +
				((v_t *)(vec->val))[i+vec->traits->nrowspadded*v] * b[v];
		}
	}
}

template<typename v_t> void ghost_vec_vscale_tmpl(ghost_vec_t *vec, void *scale)
{
	ghost_vidx_t i,v;
	v_t *s = (v_t *)scale;

	for (v=0; v<vec->traits->nvecs; v++) {
#pragma omp parallel for
		for (i=0; i<vec->traits->nrows; i++) {
			((v_t *)(vec->val))[i+vec->traits->nrowspadded*v] *= s[v];
		}
	}
}

template <typename v_t> void ghost_vec_fromRand_tmpl(ghost_vec_t *vec)
{
	vec_malloc(vec);
	DEBUG_LOG(1,"Filling vector with random values");
	size_t sizeofdt = ghost_sizeofDataType(vec->traits->datatype);

	vec->val = ghost_malloc(vec->traits->nvecs*vec->traits->nrowspadded*sizeofdt);
	int i,v;

	// TODO fuse loops but preserve randomness

	if (vec->traits->nvecs > 1) {
#pragma omp parallel for schedule(runtime) private(i)
		for (v=0; v<vec->traits->nvecs; v++) {
			for (i=0; i<vec->traits->nrows; i++) {
				((v_t *)(vec->val))[v*vec->traits->nrowspadded+i] = (v_t)0;
			}
		}
	} else {
#pragma omp parallel for schedule(runtime)
		for (i=0; i<vec->traits->nrows; i++) {
			((v_t *)(vec->val))[i] = (v_t)0;
		}
	}

	for (v=0; v<vec->traits->nvecs; v++) {
		for (i=0; i<vec->traits->nrows; i++) {
			((v_t *)(vec->val))[v*vec->traits->nrowspadded+i] = (v_t)(rand()*1./RAND_MAX); // TODO imag
		}
	}
	vec->upload(vec);

}

extern "C" void d_ghost_normalizeVector(ghost_vec_t *vec)
{ return ghost_normalizeVector_tmpl< double >(vec); }

extern "C" void s_ghost_normalizeVector(ghost_vec_t *vec)
{ return ghost_normalizeVector_tmpl< float >(vec); }

extern "C" void z_ghost_normalizeVector(ghost_vec_t *vec)
{ return ghost_normalizeVector_tmpl< ghost_complex<double> >(vec); }

extern "C" void c_ghost_normalizeVector(ghost_vec_t *vec)
{ return ghost_normalizeVector_tmpl< ghost_complex<float> >(vec); }

extern "C" void d_ghost_vec_dotprod(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ return ghost_vec_dotprod_tmpl< double >(vec,vec2,res); }

extern "C" void s_ghost_vec_dotprod(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ return ghost_vec_dotprod_tmpl< float >(vec,vec2,res); }

extern "C" void z_ghost_vec_dotprod(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ return ghost_vec_dotprod_tmpl< ghost_complex<double> >(vec,vec2,res); }

extern "C" void c_ghost_vec_dotprod(ghost_vec_t *vec, ghost_vec_t *vec2, void *res)
{ return ghost_vec_dotprod_tmpl< ghost_complex<float> >(vec,vec2,res); }

extern "C" void d_ghost_vec_vscale(ghost_vec_t *vec, void *scale)
{ return ghost_vec_vscale_tmpl< double >(vec, scale); }

extern "C" void s_ghost_vec_vscale(ghost_vec_t *vec, void *scale)
{ return ghost_vec_vscale_tmpl< float  >(vec, scale); }

extern "C" void z_ghost_vec_vscale(ghost_vec_t *vec, void *scale)
{ return ghost_vec_vscale_tmpl< ghost_complex<double> >(vec, scale); }

extern "C" void c_ghost_vec_vscale(ghost_vec_t *vec, void *scale)
{ return ghost_vec_vscale_tmpl< ghost_complex<float> >(vec, scale); }

extern "C" void d_ghost_vec_vaxpy(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{ return ghost_vec_vaxpy_tmpl< double >(vec, vec2, scale); }

extern "C" void s_ghost_vec_vaxpy(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{ return ghost_vec_vaxpy_tmpl< float >(vec, vec2, scale); }

extern "C" void z_ghost_vec_vaxpy(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{ return ghost_vec_vaxpy_tmpl< ghost_complex<double> >(vec, vec2, scale); }

extern "C" void c_ghost_vec_vaxpy(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale)
{ return ghost_vec_vaxpy_tmpl< ghost_complex<float> >(vec, vec2, scale); }

extern "C" void d_ghost_vec_vaxpby(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b)
{ return ghost_vec_vaxpby_tmpl< double >(vec, vec2, scale, b); }

extern "C" void s_ghost_vec_vaxpby(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b)
{ return ghost_vec_vaxpby_tmpl< float >(vec, vec2, scale, b); }

extern "C" void z_ghost_vec_vaxpby(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b)
{ return ghost_vec_vaxpby_tmpl< ghost_complex<double> >(vec, vec2, scale, b); }

extern "C" void c_ghost_vec_vaxpby(ghost_vec_t *vec, ghost_vec_t *vec2, void *scale, void *b)
{ return ghost_vec_vaxpby_tmpl< ghost_complex<float> >(vec, vec2, scale, b); }

extern "C" void d_ghost_vec_fromRand(ghost_vec_t *vec)
{ return ghost_vec_fromRand_tmpl< double >(vec); }

extern "C" void s_ghost_vec_fromRand(ghost_vec_t *vec)
{ return ghost_vec_fromRand_tmpl< float >(vec); }

extern "C" void z_ghost_vec_fromRand(ghost_vec_t *vec)
{ return ghost_vec_fromRand_tmpl< ghost_complex<double> >(vec); }

extern "C" void c_ghost_vec_fromRand(ghost_vec_t *vec)
{ return ghost_vec_fromRand_tmpl< ghost_complex<float> >(vec); }

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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_idl.hxx"

/****************** I N C L U D E S **************************************/
// C and C++ Includes.
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

// Programmabhngige Includes.
#include <hash.hxx>
#include <tools/debug.hxx>

/****************** C O D E **********************************************/
/*************************************************************************
|*
|*    SvStringHashEntry::~SvStringHashEntry()
|*
|*    Beschreibung
|*
*************************************************************************/
SvStringHashEntry::~SvStringHashEntry() { };

/*************************************************************************
|*
|*    SvHashTable::SvHashTable()
|*
|*    Beschreibung
|*
*************************************************************************/
SvHashTable::SvHashTable( UINT32 nMaxEntries )
{
    nMax = nMaxEntries;     // set max entries
    nFill = 0;              // no entries
    lTry = 0;
    lAsk = 0;
}

/*************************************************************************
|*
|*    SvHashTable::~SvHashTable()
|*
|*    Beschreibung
|*
*************************************************************************/
SvHashTable::~SvHashTable()
{
#ifdef DOS_NIE
    printf( "Maximum: %ld, Fllung: %ld\n", (ULONG)nMax, (ULONG)nFill );
    printf( "Anfragen: %ld, Versuche: %ld", (ULONG)lAsk, (ULONG)lTry );
    if( lTry != 0 )
        printf( ", V/E = %ld\n", lTry / lAsk );
#endif
}

/*************************************************************************
|*
|*    SvHashTable::Test_Insert()
|*
|*    Beschreibung
|*
*************************************************************************/
BOOL SvHashTable::Test_Insert( const void * pElement, BOOL bInsert,
                               UINT32 * pInsertPos )
{
    UINT32    nHash;
    UINT32    nIndex;
    UINT32    nLoop;

    lAsk++;
    lTry++;

    nHash =  HashFunc( pElement );
    nIndex = nHash % nMax;

//  const char* s = ((ByteString*) pElement)->GetStr();
//  fprintf(stderr,"### Hash: %lu , Name: %s\n",nIndex,s );

    nLoop = 0;                                      // divide to range
    while( (nMax != nLoop) && IsEntry( nIndex ) )
    {                     // is place occupied
        if( COMPARE_EQUAL == Compare( pElement, nIndex ) )
        {
            if( pInsertPos )
                *pInsertPos = nIndex;               // place of Element
            return TRUE;
        }
        nLoop++;
        lTry++;
        nIndex = (USHORT)(nIndex + nHash + 7) % nMax;
    }

    if( bInsert )
    {
        DBG_ASSERT( nMax != nLoop, "Hash table full" );
        if( nMax != nLoop )
        {
            nFill++;
            *pInsertPos = nIndex;                       // return free place
            return TRUE;
        }
    }
    return( FALSE );
}

/************************************************************************/
/*************************************************************************
|*
|*    SvStringHashTable::SvStringHashTable()
|*
|*    Beschreibung
|*
*************************************************************************/
SvStringHashTable::SvStringHashTable( UINT32 nMaxEntries )
        : SvHashTable( nMaxEntries )
{
#ifdef WIN
    DBG_ASSERT( (UINT32)nMaxEntries * sizeof( SvStringHashEntry ) <= 0xFF00,
                "Hash table size cannot exeed 64k byte" )
#endif
    pEntries = new SvStringHashEntry[ nMaxEntries ];

    // RefCount auf eins setzen
    SvStringHashEntry * pPos, *pEnd;
    pPos    = pEntries;
    pEnd    = pEntries + nMaxEntries;
    while( pPos != pEnd )
    {
        pPos->AddRef();
        pPos++;
    }
}

/*************************************************************************
|*
|*    ~SvStringHashTable::SvStringHashTable()
|*
|*    Beschreibung
|*
*************************************************************************/
SvStringHashTable::~SvStringHashTable()
{
    // RefCount auf eins setzen
    SvStringHashEntry * pPos, *pEnd;
    pPos    = pEntries;
    pEnd    = pEntries + GetMax();
#ifdef DBG_UTIL
    while( pPos != pEnd )
    {
        DBG_ASSERT( pPos->GetRefCount() == 1, "Reference count != 1" );
        pPos++;
    }
#endif

#ifdef MPW
    // der MPW-Compiler ruft sonst keine Dtoren!
    for ( USHORT n = 0; n < GetMax(); ++n )
        (pEntries+n)->SvStringHashEntry::~SvStringHashEntry();
    delete (void*) pEntries;
#else
    delete [] pEntries;
#endif
}

/*************************************************************************
|*
|*    SvStringHashTable::HashFunc()
|*
|*    Beschreibung
|*
*************************************************************************/
UINT32 SvStringHashTable::HashFunc( const void * pElement ) const
{
    UINT32          nHash = 0;  // hash value
    const char *    pStr = ((const ByteString * )pElement)->GetBuffer();

    int nShift = 0;
    while( *pStr )
    {
        if( isupper( *pStr ) )
            nHash ^= UINT32(*pStr - 'A' + 26) << nShift;
        else
            nHash ^= UINT32(*pStr - 'a') << nShift;
        if( nShift == 28 )
            nShift = 0;
        else
            nShift += 4;
        pStr++;
    }
    return( nHash );
}

/*************************************************************************
|*
|*    SvStringHashTable::GetNearString()
|*
|*    Beschreibung
|*
*************************************************************************/
ByteString SvStringHashTable::GetNearString( const ByteString & rName ) const
{
    for( UINT32 i = 0; i < GetMax(); i++ )
    {
        SvStringHashEntry * pE = Get( i );
        if( pE )
        {
            if( pE->GetName().EqualsIgnoreCaseAscii( rName ) && !pE->GetName().Equals( rName ) )
                return pE->GetName();
        }
    }
    return ByteString();
}

/*************************************************************************
|*
|*    SvStringHashTable::IsEntry()
|*
|*    Beschreibung
|*
*************************************************************************/
BOOL SvStringHashTable::IsEntry( UINT32 nIndex ) const
{
    if( nIndex >= GetMax() )
        return FALSE;
    return pEntries[ nIndex ].HasId();
}

/*************************************************************************
|*
|*    SvStringHashTable::Insert()
|*
|*    Beschreibung
|*
*************************************************************************/
BOOL SvStringHashTable::Insert( const ByteString & rName, UINT32 * pIndex )
{
    UINT32 nIndex;

    if( !pIndex ) pIndex = &nIndex;

    if( !SvHashTable::Test_Insert( &rName, TRUE, pIndex ) )
        return FALSE;

    if( !IsEntry( *pIndex ) )
        pEntries[ *pIndex ] = SvStringHashEntry( rName, *pIndex );
    return TRUE;
}

/*************************************************************************
|*
|*    SvStringHashTable::Test()
|*
|*    Beschreibung
|*
*************************************************************************/
BOOL SvStringHashTable::Test( const ByteString & rName, UINT32 * pPos ) const
{
    return ((SvStringHashTable *)this)->SvHashTable::
                Test_Insert( &rName, FALSE, pPos );
}

/*************************************************************************
|*
|*    SvStringHashTable::Get()
|*
|*    Beschreibung
|*
*************************************************************************/
SvStringHashEntry * SvStringHashTable::Get( UINT32 nIndex ) const
{
    if( IsEntry( nIndex ) )
        return pEntries + nIndex;
    return( NULL );
}

/*************************************************************************
|*
|*    SvStringHashTable::Get()
|*
|*    Beschreibung
|*
*************************************************************************/
StringCompare SvStringHashTable::Compare( const void * pElement,
                                          UINT32 nIndex ) const
{
    return ((const ByteString *)pElement)->CompareTo( pEntries[ nIndex ].GetName() );
}

/*************************************************************************
|*
|*    SvStringHashTable::FillHashList()
|*
|*    Beschreibung
|*
*************************************************************************/
void SvStringHashTable::FillHashList( SvStringHashList * pList ) const
{
    for( UINT32 n = 0; n < GetMax(); n++ )
    {
        if( IsEntry( n ) )
            pList->Insert( Get( n ), LIST_APPEND );
    }
    // Hash Reihenfolge, jetzt sortieren
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>cppcheck: unused variables<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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_idl.hxx"

/****************** I N C L U D E S **************************************/
// C and C++ Includes.
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

// Programmabhngige Includes.
#include <hash.hxx>
#include <tools/debug.hxx>

/****************** C O D E **********************************************/
/*************************************************************************
|*
|*    SvStringHashEntry::~SvStringHashEntry()
|*
|*    Beschreibung
|*
*************************************************************************/
SvStringHashEntry::~SvStringHashEntry() { };

/*************************************************************************
|*
|*    SvHashTable::SvHashTable()
|*
|*    Beschreibung
|*
*************************************************************************/
SvHashTable::SvHashTable( UINT32 nMaxEntries )
{
    nMax = nMaxEntries;     // set max entries
    nFill = 0;              // no entries
    lTry = 0;
    lAsk = 0;
}

/*************************************************************************
|*
|*    SvHashTable::~SvHashTable()
|*
|*    Beschreibung
|*
*************************************************************************/
SvHashTable::~SvHashTable()
{
#ifdef DOS_NIE
    printf( "Maximum: %ld, Fllung: %ld\n", (ULONG)nMax, (ULONG)nFill );
    printf( "Anfragen: %ld, Versuche: %ld", (ULONG)lAsk, (ULONG)lTry );
    if( lTry != 0 )
        printf( ", V/E = %ld\n", lTry / lAsk );
#endif
}

/*************************************************************************
|*
|*    SvHashTable::Test_Insert()
|*
|*    Beschreibung
|*
*************************************************************************/
BOOL SvHashTable::Test_Insert( const void * pElement, BOOL bInsert,
                               UINT32 * pInsertPos )
{
    UINT32    nHash;
    UINT32    nIndex;
    UINT32    nLoop;

    lAsk++;
    lTry++;

    nHash =  HashFunc( pElement );
    nIndex = nHash % nMax;

//  const char* s = ((ByteString*) pElement)->GetStr();
//  fprintf(stderr,"### Hash: %lu , Name: %s\n",nIndex,s );

    nLoop = 0;                                      // divide to range
    while( (nMax != nLoop) && IsEntry( nIndex ) )
    {                     // is place occupied
        if( COMPARE_EQUAL == Compare( pElement, nIndex ) )
        {
            if( pInsertPos )
                *pInsertPos = nIndex;               // place of Element
            return TRUE;
        }
        nLoop++;
        lTry++;
        nIndex = (USHORT)(nIndex + nHash + 7) % nMax;
    }

    if( bInsert )
    {
        DBG_ASSERT( nMax != nLoop, "Hash table full" );
        if( nMax != nLoop )
        {
            nFill++;
            *pInsertPos = nIndex;                       // return free place
            return TRUE;
        }
    }
    return( FALSE );
}

/************************************************************************/
/*************************************************************************
|*
|*    SvStringHashTable::SvStringHashTable()
|*
|*    Beschreibung
|*
*************************************************************************/
SvStringHashTable::SvStringHashTable( UINT32 nMaxEntries )
        : SvHashTable( nMaxEntries )
{
#ifdef WIN
    DBG_ASSERT( (UINT32)nMaxEntries * sizeof( SvStringHashEntry ) <= 0xFF00,
                "Hash table size cannot exeed 64k byte" )
#endif
    pEntries = new SvStringHashEntry[ nMaxEntries ];

    // RefCount auf eins setzen
    SvStringHashEntry * pPos, *pEnd;
    pPos    = pEntries;
    pEnd    = pEntries + nMaxEntries;
    while( pPos != pEnd )
    {
        pPos->AddRef();
        pPos++;
    }
}

/*************************************************************************
|*
|*    ~SvStringHashTable::SvStringHashTable()
|*
|*    Beschreibung
|*
*************************************************************************/
SvStringHashTable::~SvStringHashTable()
{
#ifdef DBG_UTIL
    // RefCount auf eins setzen
    SvStringHashEntry * pPos, *pEnd;
    pPos    = pEntries;
    pEnd    = pEntries + GetMax();
    while( pPos != pEnd )
    {
        DBG_ASSERT( pPos->GetRefCount() == 1, "Reference count != 1" );
        pPos++;
    }
#endif

#ifdef MPW
    // der MPW-Compiler ruft sonst keine Dtoren!
    for ( USHORT n = 0; n < GetMax(); ++n )
        (pEntries+n)->SvStringHashEntry::~SvStringHashEntry();
    delete (void*) pEntries;
#else
    delete [] pEntries;
#endif
}

/*************************************************************************
|*
|*    SvStringHashTable::HashFunc()
|*
|*    Beschreibung
|*
*************************************************************************/
UINT32 SvStringHashTable::HashFunc( const void * pElement ) const
{
    UINT32          nHash = 0;  // hash value
    const char *    pStr = ((const ByteString * )pElement)->GetBuffer();

    int nShift = 0;
    while( *pStr )
    {
        if( isupper( *pStr ) )
            nHash ^= UINT32(*pStr - 'A' + 26) << nShift;
        else
            nHash ^= UINT32(*pStr - 'a') << nShift;
        if( nShift == 28 )
            nShift = 0;
        else
            nShift += 4;
        pStr++;
    }
    return( nHash );
}

/*************************************************************************
|*
|*    SvStringHashTable::GetNearString()
|*
|*    Beschreibung
|*
*************************************************************************/
ByteString SvStringHashTable::GetNearString( const ByteString & rName ) const
{
    for( UINT32 i = 0; i < GetMax(); i++ )
    {
        SvStringHashEntry * pE = Get( i );
        if( pE )
        {
            if( pE->GetName().EqualsIgnoreCaseAscii( rName ) && !pE->GetName().Equals( rName ) )
                return pE->GetName();
        }
    }
    return ByteString();
}

/*************************************************************************
|*
|*    SvStringHashTable::IsEntry()
|*
|*    Beschreibung
|*
*************************************************************************/
BOOL SvStringHashTable::IsEntry( UINT32 nIndex ) const
{
    if( nIndex >= GetMax() )
        return FALSE;
    return pEntries[ nIndex ].HasId();
}

/*************************************************************************
|*
|*    SvStringHashTable::Insert()
|*
|*    Beschreibung
|*
*************************************************************************/
BOOL SvStringHashTable::Insert( const ByteString & rName, UINT32 * pIndex )
{
    UINT32 nIndex;

    if( !pIndex ) pIndex = &nIndex;

    if( !SvHashTable::Test_Insert( &rName, TRUE, pIndex ) )
        return FALSE;

    if( !IsEntry( *pIndex ) )
        pEntries[ *pIndex ] = SvStringHashEntry( rName, *pIndex );
    return TRUE;
}

/*************************************************************************
|*
|*    SvStringHashTable::Test()
|*
|*    Beschreibung
|*
*************************************************************************/
BOOL SvStringHashTable::Test( const ByteString & rName, UINT32 * pPos ) const
{
    return ((SvStringHashTable *)this)->SvHashTable::
                Test_Insert( &rName, FALSE, pPos );
}

/*************************************************************************
|*
|*    SvStringHashTable::Get()
|*
|*    Beschreibung
|*
*************************************************************************/
SvStringHashEntry * SvStringHashTable::Get( UINT32 nIndex ) const
{
    if( IsEntry( nIndex ) )
        return pEntries + nIndex;
    return( NULL );
}

/*************************************************************************
|*
|*    SvStringHashTable::Get()
|*
|*    Beschreibung
|*
*************************************************************************/
StringCompare SvStringHashTable::Compare( const void * pElement,
                                          UINT32 nIndex ) const
{
    return ((const ByteString *)pElement)->CompareTo( pEntries[ nIndex ].GetName() );
}

/*************************************************************************
|*
|*    SvStringHashTable::FillHashList()
|*
|*    Beschreibung
|*
*************************************************************************/
void SvStringHashTable::FillHashList( SvStringHashList * pList ) const
{
    for( UINT32 n = 0; n < GetMax(); n++ )
    {
        if( IsEntry( n ) )
            pList->Insert( Get( n ), LIST_APPEND );
    }
    // Hash Reihenfolge, jetzt sortieren
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/******************************************************************************
 ** Copyright (c) 2010 Seed Developers
 ** All rights reserved
 ** Contact: licensing@seedframework.org
 ** Website: http://www.seedframework.org

 ** This file is part of the Seed Framework.

 ** Commercial Usage
 ** Seed Framework is available under proprietary license for those who cannot,
 ** or choose not to, use LGPL and GPL code in their projects (eg. iPhone,
 ** Nintendo Wii and others).

 ** GNU Lesser General Public License Usage
 ** Alternatively, this file may be used under the terms of the GNU Lesser
 ** General Public License version 2.1 as published by the Free Software
 ** Foundation and appearing in the file LICENSE.LGPL included in the
 ** packaging of this file.  Please review the following information to
 ** ensure the GNU Lesser General Public License version 2.1 requirements
 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
 ** In addition, as a special exception, Seed developers gives you certain
 ** additional rights. These rights are described in the Seed Framework LGPL
 ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
 ** package.
 **
 ** If you have questions regarding the use of this file, please contact
 ** Seed developers at licensing@seedframework.org.
 **
 *****************************************************************************/

/*! \file Timeline.cpp
	\author	Rafael Eduardo Gonchor
	\brief Timeline implementation to be used with ITransformable2D objects
*/

#include "Timeline.h"
#include "EventMovie.h"
#include "Movie.h"

namespace Seed {

Timeline::Timeline()
	: pParent(NULL)
	, pObject(NULL)
	, pListener(NULL)
	, fElapsedTime(0.0f)
	, fElapsedKeyframeTime(0.0f)
	, iCurrentFrame(0)
	, iKeyframeFrom(0)
	, iKeyframeTo(0)
	, arKeyframes()
{
	MEMSET(arKeyframes, '\0', sizeof(Keyframe *) * MAX_KEYFRAMES);
}

Timeline::~Timeline()
{
	this->Reset();
}

INLINE void Timeline::Reset()
{
	MEMSET(arKeyframes, '\0', sizeof(Keyframe *) * MAX_KEYFRAMES);

	fElapsedTime 			= 0.0f;
	fElapsedKeyframeTime 	= 0.0f;
	iCurrentFrame 			= 0;
	iKeyframeFrom 			= 0;
	iKeyframeTo 			= 0;
}

INLINE void Timeline::Rewind()
{
	iCurrentFrame			= 0;
	iKeyframeFrom 			= 0;
	iKeyframeTo 			= 0;
	fElapsedTime 			= 0.0f;
	fElapsedKeyframeTime 	= 0.0f;
}

INLINE void Timeline::AddKeyframe(u32 frame, Keyframe *keyframe)
{
	ASSERT_MSG(frame < MAX_KEYFRAMES, "Keyframe out of range.");
	arKeyframes[frame] = keyframe;
}

void Timeline::GotoAndPlay(u32 frame)
{
	iCurrentFrame	= frame;
	iKeyframeFrom	= FindPreviousKeyframe();
	iKeyframeTo		= FindNextKeyframe();
}

void Timeline::GotoAndPlay(const char *strKeyframeName)
{
	iKeyframeFrom	= FindKeyframeByName(strKeyframeName);
	iKeyframeTo		= FindNextKeyframe();
	iCurrentFrame	= iKeyframeFrom;
}

void Timeline::Update()
{
	if (!pObject)
		return;

	//attempt to get the next keyframe
	if (iKeyframeTo <= 0)
	{
		iKeyframeTo = FindNextKeyframe();
		//end of animation, restart
		if (iKeyframeTo < 0)
		{
			if (pListener)
			{
				EventMovie ev(this, arKeyframes[iCurrentFrame], static_cast<u32>(iCurrentFrame));
				pListener->OnTimelineFrame(&ev);
				pListener->OnTimelineRestart(&ev);
			}

			iKeyframeFrom = 0;
			iCurrentFrame = 0;
			this->Update();
			return;
		}
	}

	//start interpolating keyframes
	Keyframe *kfFrom	= arKeyframes[iKeyframeFrom];
	Keyframe *kfTo 		= arKeyframes[iKeyframeTo];

	ASSERT_MSG(kfFrom, 	"A keyframe is required at frame 0.");
	ASSERT_MSG(kfTo, 	"At least two keyframes must be set.");

	if (pListener)
	{
		EventMovie ev(this, kfFrom, static_cast<u32>(iCurrentFrame));
		pListener->OnTimelineFrame(&ev);
	}

	f32 fBegin 		= static_cast<f32>(iCurrentFrame - iKeyframeFrom);
	f32 fDuration 	= static_cast<f32>(iKeyframeTo - iKeyframeFrom);

	//Raptor note: Timeline should only change the position and orientation of the object NEVER
	//its visibility or rendering state
	//pObject->SetVisible(!kfFrom->bBlank);
	if (!kfFrom->bBlank)
	{
		//calculate the interpolated values
		f32 fCurrRot,
			fCurrPosX,
			fCurrPosY,
			fCurrLocalPosX,
			fCurrLocalPosY,
			fCurrScaleX,
			fCurrScaleY,
			fCurrR,
			fCurrG,
			fCurrB,
			fCurrA;

		if (kfFrom->bTween && !kfTo->bBlank)
		{
			fCurrRot		= EaseQuadPercent(	fBegin,
												kfFrom->fRotation,
												(kfTo->fRotation - kfFrom->fRotation),
												fDuration,
												kfFrom->fEasing);

			fCurrPosX		= EaseQuadPercent(	fBegin,
												kfFrom->ptPos.x,
												(kfTo->ptPos.x - kfFrom->ptPos.x),
												fDuration,
												kfFrom->fEasing);

			fCurrPosY		= EaseQuadPercent(	fBegin,
												kfFrom->ptPos.y,
												(kfTo->ptPos.y - kfFrom->ptPos.y),
												fDuration,
												kfFrom->fEasing);

			fCurrLocalPosX	= EaseQuadPercent(	fBegin,
												kfFrom->ptLocalPos.x,
												(kfTo->ptLocalPos.x - kfFrom->ptLocalPos.x),
												fDuration,
												kfFrom->fEasing);

			fCurrLocalPosY	= EaseQuadPercent(	fBegin,
												kfFrom->ptLocalPos.y,
												(kfTo->ptLocalPos.y - kfFrom->ptLocalPos.y),
												fDuration,
												kfFrom->fEasing);

			fCurrScaleX		= EaseQuadPercent(	fBegin,
												kfFrom->ptScale.x,
												(kfTo->ptScale.x - kfFrom->ptScale.x),
												fDuration,
												kfFrom->fEasing);

			fCurrScaleY		= EaseQuadPercent(	fBegin,
												kfFrom->ptScale.y,
												(kfTo->ptScale.y - kfFrom->ptScale.y),
												fDuration,
												kfFrom->fEasing);

			fCurrR			= EaseQuadPercent(	fBegin,
												(f32)kfFrom->iColorR,
												((f32)kfTo->iColorR - (f32)kfFrom->iColorR),
												fDuration,
												kfFrom->fEasing);

			fCurrG			= EaseQuadPercent(	fBegin,
												(f32)kfFrom->iColorG,
												((f32)kfTo->iColorG - (f32)kfFrom->iColorG),
												fDuration,
												kfFrom->fEasing);

			fCurrB			= EaseQuadPercent(	fBegin,
												(f32)kfFrom->iColorB,
												((f32)kfTo->iColorB - (f32)kfFrom->iColorB),
												fDuration,
												kfFrom->fEasing);

			fCurrA			= EaseQuadPercent(	fBegin,
												(f32)kfFrom->iColorA,
												((f32)kfTo->iColorA - (f32)kfFrom->iColorA),
												fDuration,
												kfFrom->fEasing);
		}
		else
		{
			fCurrRot 		= kfFrom->fRotation;
			fCurrPosX		= kfFrom->ptPos.x;
			fCurrPosY		= kfFrom->ptPos.y;
			fCurrLocalPosX	= kfFrom->ptLocalPos.x;
			fCurrLocalPosY	= kfFrom->ptLocalPos.y;
			fCurrScaleX		= kfFrom->ptScale.x;
			fCurrScaleY		= kfFrom->ptScale.y;
			fCurrR			= kfFrom->iColorR;
			fCurrG			= kfFrom->iColorG;
			fCurrB			= kfFrom->iColorB;
			fCurrA			= kfFrom->iColorA;
		}

		if(pObject)
		{
			pObject->SetPosition(fCurrPosX, fCurrPosY);
			pObject->SetLocalPosition(fCurrLocalPosX, fCurrLocalPosY);
			pObject->SetRotation(fCurrRot);
			pObject->SetScale(fCurrScaleX, fCurrScaleY);
			pObject->SetColor((u32)fCurrR, (u32)fCurrG, (u32)fCurrB, (u32)fCurrA);
		}
	}

	if ((fBegin / fDuration) >= 1.0f)
	{
		switch (kfTo->iEvent)
		{
			case Keyframe::KEYFRAME_EVENT_NONE:
			{
				iKeyframeFrom 	= iKeyframeTo;
				iKeyframeTo 	= FindNextKeyframe();
			}
			break;

			case Keyframe::KEYFRAME_EVENT_STOP:
			{
				iKeyframeFrom = iKeyframeTo;
			}
			break;

			case Keyframe::KEYFRAME_EVENT_RESTART:
			{
				iKeyframeFrom = 0;
				iKeyframeTo   = -1;
				iCurrentFrame = 0;
				return;
			}
			break;

			case Keyframe::KEYFRAME_EVENT_JUMPTOFRAME:
			{
				iCurrentFrame = kfTo->iFrameToJump;
				iKeyframeFrom = FindPreviousKeyframe();
				iKeyframeTo   = FindNextKeyframe();
				return;
			}
			break;
		}
	}
	else
	{
		switch (kfFrom->iEvent)
		{
			case Keyframe::KEYFRAME_EVENT_STOP:
			{
				iKeyframeTo		= iKeyframeFrom;
				iCurrentFrame	= iKeyframeFrom;
				return;
			}
			break;
		}
	}

	//FIXME when changing to timebased instead of framebased the iCurrentFrame increment must
	//be based on the elapsedtime
	fElapsedKeyframeTime++;
	fElapsedTime++;
	iCurrentFrame++;
}

INLINE ISceneObject *Timeline::GetObject() const
{
	return pObject;
}

INLINE f32 Timeline::GetWidth() const
{
	f32 r = 0.0f;
	if (pObject)
		r = pObject->GetWidth();

	return r;
}

INLINE f32 Timeline::GetHeight() const
{
	f32 r = 0.0f;
	if (pObject)
		r = pObject->GetHeight();

	return r;
}

INLINE u32 Timeline::GetCurrentFrame() const
{
	return static_cast<u32>(iCurrentFrame);
}

INLINE void Timeline::SetLocalPosition(f32 posX, f32 posY)
{
	ptParentLocalPosition.x = posX;
	ptParentLocalPosition.y = posY;
}

INLINE void Timeline::SetPosition(f32 posX, f32 posY)
{
	ptParentPosition.x = posX;
	ptParentPosition.y = posY;
}

INLINE void Timeline::SetScale(f32 scaleX, f32 scaleY)
{
	ptParentScale.x = scaleX;
	ptParentScale.y = scaleY;
}

INLINE void Timeline::SetRotation(f32 rotation)
{
	fParentRotation = rotation;
}

INLINE s32 Timeline::FindKeyframeByName(const char *pstrName)
{
	for (s32 i = 0; i < MAX_KEYFRAMES; i++)
	{
		if (!arKeyframes[i])
			continue;
		else if (!STRCMP(arKeyframes[i]->pstrName, pstrName))
			return i;
	}

	return 0;
}

INLINE s32 Timeline::FindNextKeyframe()
{
	for (s32 i = iKeyframeFrom+1; i < MAX_KEYFRAMES; i++)
	{
		if (!arKeyframes[i])
			continue;
		else
			return i;
	}

	return -1;
}

INLINE s32 Timeline::FindPreviousKeyframe()
{
	for (s32 i = iCurrentFrame; i >= 0; i--)
	{
		if (!arKeyframes[i])
			continue;
		else
			return i;
	}

	return -1;
}

INLINE void Timeline::SetListener(IEventMovieListener *listener)
{
	this->pListener = listener;
}

INLINE const Keyframe *Timeline::GetCurrentKeyframe() const
{
	return arKeyframes[iKeyframeFrom];
}

INLINE f32 Timeline::EaseQuadPercent(f32 time, f32 begin, f32 change, f32 duration, f32 easing)
{
	if (duration <= 0.0f)
		return begin;

	if (time <= 0.0)
		return begin;

	if ((time /= duration) >= 1.0f)
		return begin + change;

	// linear tween if percent is 0
	if (!easing)
		return change * time + begin;

	if (easing > 1.0f)
		easing = 1.0f;
	else if (easing < -1.0f)
		easing = -1.0f;

	// ease in if percent is negative
	if (easing < 0.0f)
		return change * time * (time * (-easing) + (1.0f + easing)) + begin;

	// ease out if percent is positive
	return change * time * ((2.0f - time) * easing + (1.0f - easing)) + begin;
}

INLINE void Timeline::SetObject(ISceneObject *object)
{
	pObject = object;
	if (pParent && object)
		pParent->Add(pObject);
}

INLINE void Timeline::SetParent(Movie *parent)
{
	pParent = parent;
	if (pObject)
		parent->Add(pObject);
}

INLINE Movie *Timeline::GetParent() const
{
	return pParent;
}

} // namespace
<commit_msg>+ Timeline remove child from parent when changing objects;<commit_after>/******************************************************************************
 ** Copyright (c) 2010 Seed Developers
 ** All rights reserved
 ** Contact: licensing@seedframework.org
 ** Website: http://www.seedframework.org

 ** This file is part of the Seed Framework.

 ** Commercial Usage
 ** Seed Framework is available under proprietary license for those who cannot,
 ** or choose not to, use LGPL and GPL code in their projects (eg. iPhone,
 ** Nintendo Wii and others).

 ** GNU Lesser General Public License Usage
 ** Alternatively, this file may be used under the terms of the GNU Lesser
 ** General Public License version 2.1 as published by the Free Software
 ** Foundation and appearing in the file LICENSE.LGPL included in the
 ** packaging of this file.  Please review the following information to
 ** ensure the GNU Lesser General Public License version 2.1 requirements
 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
 ** In addition, as a special exception, Seed developers gives you certain
 ** additional rights. These rights are described in the Seed Framework LGPL
 ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
 ** package.
 **
 ** If you have questions regarding the use of this file, please contact
 ** Seed developers at licensing@seedframework.org.
 **
 *****************************************************************************/

/*! \file Timeline.cpp
	\author	Rafael Eduardo Gonchor
	\brief Timeline implementation to be used with ITransformable2D objects
*/

#include "Timeline.h"
#include "EventMovie.h"
#include "Movie.h"

namespace Seed {

Timeline::Timeline()
	: pParent(NULL)
	, pObject(NULL)
	, pListener(NULL)
	, fElapsedTime(0.0f)
	, fElapsedKeyframeTime(0.0f)
	, iCurrentFrame(0)
	, iKeyframeFrom(0)
	, iKeyframeTo(0)
	, arKeyframes()
{
	MEMSET(arKeyframes, '\0', sizeof(Keyframe *) * MAX_KEYFRAMES);
}

Timeline::~Timeline()
{
	this->Reset();
}

INLINE void Timeline::Reset()
{
	MEMSET(arKeyframes, '\0', sizeof(Keyframe *) * MAX_KEYFRAMES);

	fElapsedTime 			= 0.0f;
	fElapsedKeyframeTime 	= 0.0f;
	iCurrentFrame 			= 0;
	iKeyframeFrom 			= 0;
	iKeyframeTo 			= 0;
}

INLINE void Timeline::Rewind()
{
	iCurrentFrame			= 0;
	iKeyframeFrom 			= 0;
	iKeyframeTo 			= 0;
	fElapsedTime 			= 0.0f;
	fElapsedKeyframeTime 	= 0.0f;
}

INLINE void Timeline::AddKeyframe(u32 frame, Keyframe *keyframe)
{
	ASSERT_MSG(frame < MAX_KEYFRAMES, "Keyframe out of range.");
	arKeyframes[frame] = keyframe;
}

void Timeline::GotoAndPlay(u32 frame)
{
	iCurrentFrame	= frame;
	iKeyframeFrom	= FindPreviousKeyframe();
	iKeyframeTo		= FindNextKeyframe();
}

void Timeline::GotoAndPlay(const char *strKeyframeName)
{
	iKeyframeFrom	= FindKeyframeByName(strKeyframeName);
	iKeyframeTo		= FindNextKeyframe();
	iCurrentFrame	= iKeyframeFrom;
}

void Timeline::Update()
{
	if (!pObject)
		return;

	//attempt to get the next keyframe
	if (iKeyframeTo <= 0)
	{
		iKeyframeTo = FindNextKeyframe();
		//end of animation, restart
		if (iKeyframeTo < 0)
		{
			if (pListener)
			{
				EventMovie ev(this, arKeyframes[iCurrentFrame], static_cast<u32>(iCurrentFrame));
				pListener->OnTimelineFrame(&ev);
				pListener->OnTimelineRestart(&ev);
			}

			iKeyframeFrom = 0;
			iCurrentFrame = 0;
			this->Update();
			return;
		}
	}

	//start interpolating keyframes
	Keyframe *kfFrom	= arKeyframes[iKeyframeFrom];
	Keyframe *kfTo 		= arKeyframes[iKeyframeTo];

	ASSERT_MSG(kfFrom, 	"A keyframe is required at frame 0.");
	ASSERT_MSG(kfTo, 	"At least two keyframes must be set.");

	if (pListener)
	{
		EventMovie ev(this, kfFrom, static_cast<u32>(iCurrentFrame));
		pListener->OnTimelineFrame(&ev);
	}

	f32 fBegin 		= static_cast<f32>(iCurrentFrame - iKeyframeFrom);
	f32 fDuration 	= static_cast<f32>(iKeyframeTo - iKeyframeFrom);

	//Raptor note: Timeline should only change the position and orientation of the object NEVER
	//its visibility or rendering state
	//pObject->SetVisible(!kfFrom->bBlank);
	if (!kfFrom->bBlank)
	{
		//calculate the interpolated values
		f32 fCurrRot,
			fCurrPosX,
			fCurrPosY,
			fCurrLocalPosX,
			fCurrLocalPosY,
			fCurrScaleX,
			fCurrScaleY,
			fCurrR,
			fCurrG,
			fCurrB,
			fCurrA;

		if (kfFrom->bTween && !kfTo->bBlank)
		{
			fCurrRot		= EaseQuadPercent(	fBegin,
												kfFrom->fRotation,
												(kfTo->fRotation - kfFrom->fRotation),
												fDuration,
												kfFrom->fEasing);

			fCurrPosX		= EaseQuadPercent(	fBegin,
												kfFrom->ptPos.x,
												(kfTo->ptPos.x - kfFrom->ptPos.x),
												fDuration,
												kfFrom->fEasing);

			fCurrPosY		= EaseQuadPercent(	fBegin,
												kfFrom->ptPos.y,
												(kfTo->ptPos.y - kfFrom->ptPos.y),
												fDuration,
												kfFrom->fEasing);

			fCurrLocalPosX	= EaseQuadPercent(	fBegin,
												kfFrom->ptLocalPos.x,
												(kfTo->ptLocalPos.x - kfFrom->ptLocalPos.x),
												fDuration,
												kfFrom->fEasing);

			fCurrLocalPosY	= EaseQuadPercent(	fBegin,
												kfFrom->ptLocalPos.y,
												(kfTo->ptLocalPos.y - kfFrom->ptLocalPos.y),
												fDuration,
												kfFrom->fEasing);

			fCurrScaleX		= EaseQuadPercent(	fBegin,
												kfFrom->ptScale.x,
												(kfTo->ptScale.x - kfFrom->ptScale.x),
												fDuration,
												kfFrom->fEasing);

			fCurrScaleY		= EaseQuadPercent(	fBegin,
												kfFrom->ptScale.y,
												(kfTo->ptScale.y - kfFrom->ptScale.y),
												fDuration,
												kfFrom->fEasing);

			fCurrR			= EaseQuadPercent(	fBegin,
												(f32)kfFrom->iColorR,
												((f32)kfTo->iColorR - (f32)kfFrom->iColorR),
												fDuration,
												kfFrom->fEasing);

			fCurrG			= EaseQuadPercent(	fBegin,
												(f32)kfFrom->iColorG,
												((f32)kfTo->iColorG - (f32)kfFrom->iColorG),
												fDuration,
												kfFrom->fEasing);

			fCurrB			= EaseQuadPercent(	fBegin,
												(f32)kfFrom->iColorB,
												((f32)kfTo->iColorB - (f32)kfFrom->iColorB),
												fDuration,
												kfFrom->fEasing);

			fCurrA			= EaseQuadPercent(	fBegin,
												(f32)kfFrom->iColorA,
												((f32)kfTo->iColorA - (f32)kfFrom->iColorA),
												fDuration,
												kfFrom->fEasing);
		}
		else
		{
			fCurrRot 		= kfFrom->fRotation;
			fCurrPosX		= kfFrom->ptPos.x;
			fCurrPosY		= kfFrom->ptPos.y;
			fCurrLocalPosX	= kfFrom->ptLocalPos.x;
			fCurrLocalPosY	= kfFrom->ptLocalPos.y;
			fCurrScaleX		= kfFrom->ptScale.x;
			fCurrScaleY		= kfFrom->ptScale.y;
			fCurrR			= kfFrom->iColorR;
			fCurrG			= kfFrom->iColorG;
			fCurrB			= kfFrom->iColorB;
			fCurrA			= kfFrom->iColorA;
		}

		if(pObject)
		{
			pObject->SetPosition(fCurrPosX, fCurrPosY);
			pObject->SetLocalPosition(fCurrLocalPosX, fCurrLocalPosY);
			pObject->SetRotation(fCurrRot);
			pObject->SetScale(fCurrScaleX, fCurrScaleY);
			pObject->SetColor((u32)fCurrR, (u32)fCurrG, (u32)fCurrB, (u32)fCurrA);
		}
	}

	if ((fBegin / fDuration) >= 1.0f)
	{
		switch (kfTo->iEvent)
		{
			case Keyframe::KEYFRAME_EVENT_NONE:
			{
				iKeyframeFrom 	= iKeyframeTo;
				iKeyframeTo 	= FindNextKeyframe();
			}
			break;

			case Keyframe::KEYFRAME_EVENT_STOP:
			{
				iKeyframeFrom = iKeyframeTo;
			}
			break;

			case Keyframe::KEYFRAME_EVENT_RESTART:
			{
				iKeyframeFrom = 0;
				iKeyframeTo   = -1;
				iCurrentFrame = 0;
				return;
			}
			break;

			case Keyframe::KEYFRAME_EVENT_JUMPTOFRAME:
			{
				iCurrentFrame = kfTo->iFrameToJump;
				iKeyframeFrom = FindPreviousKeyframe();
				iKeyframeTo   = FindNextKeyframe();
				return;
			}
			break;
		}
	}
	else
	{
		switch (kfFrom->iEvent)
		{
			case Keyframe::KEYFRAME_EVENT_STOP:
			{
				iKeyframeTo		= iKeyframeFrom;
				iCurrentFrame	= iKeyframeFrom;
				return;
			}
			break;
		}
	}

	//FIXME when changing to timebased instead of framebased the iCurrentFrame increment must
	//be based on the elapsedtime
	fElapsedKeyframeTime++;
	fElapsedTime++;
	iCurrentFrame++;
}

INLINE ISceneObject *Timeline::GetObject() const
{
	return pObject;
}

INLINE f32 Timeline::GetWidth() const
{
	f32 r = 0.0f;
	if (pObject)
		r = pObject->GetWidth();

	return r;
}

INLINE f32 Timeline::GetHeight() const
{
	f32 r = 0.0f;
	if (pObject)
		r = pObject->GetHeight();

	return r;
}

INLINE u32 Timeline::GetCurrentFrame() const
{
	return static_cast<u32>(iCurrentFrame);
}

INLINE void Timeline::SetLocalPosition(f32 posX, f32 posY)
{
	ptParentLocalPosition.x = posX;
	ptParentLocalPosition.y = posY;
}

INLINE void Timeline::SetPosition(f32 posX, f32 posY)
{
	ptParentPosition.x = posX;
	ptParentPosition.y = posY;
}

INLINE void Timeline::SetScale(f32 scaleX, f32 scaleY)
{
	ptParentScale.x = scaleX;
	ptParentScale.y = scaleY;
}

INLINE void Timeline::SetRotation(f32 rotation)
{
	fParentRotation = rotation;
}

INLINE s32 Timeline::FindKeyframeByName(const char *pstrName)
{
	for (s32 i = 0; i < MAX_KEYFRAMES; i++)
	{
		if (!arKeyframes[i])
			continue;
		else if (!STRCMP(arKeyframes[i]->pstrName, pstrName))
			return i;
	}

	return 0;
}

INLINE s32 Timeline::FindNextKeyframe()
{
	for (s32 i = iKeyframeFrom+1; i < MAX_KEYFRAMES; i++)
	{
		if (!arKeyframes[i])
			continue;
		else
			return i;
	}

	return -1;
}

INLINE s32 Timeline::FindPreviousKeyframe()
{
	for (s32 i = iCurrentFrame; i >= 0; i--)
	{
		if (!arKeyframes[i])
			continue;
		else
			return i;
	}

	return -1;
}

INLINE void Timeline::SetListener(IEventMovieListener *listener)
{
	this->pListener = listener;
}

INLINE const Keyframe *Timeline::GetCurrentKeyframe() const
{
	return arKeyframes[iKeyframeFrom];
}

INLINE f32 Timeline::EaseQuadPercent(f32 time, f32 begin, f32 change, f32 duration, f32 easing)
{
	if (duration <= 0.0f)
		return begin;

	if (time <= 0.0)
		return begin;

	if ((time /= duration) >= 1.0f)
		return begin + change;

	// linear tween if percent is 0
	if (!easing)
		return change * time + begin;

	if (easing > 1.0f)
		easing = 1.0f;
	else if (easing < -1.0f)
		easing = -1.0f;

	// ease in if percent is negative
	if (easing < 0.0f)
		return change * time * (time * (-easing) + (1.0f + easing)) + begin;

	// ease out if percent is positive
	return change * time * ((2.0f - time) * easing + (1.0f - easing)) + begin;
}

INLINE void Timeline::SetObject(ISceneObject *object)
{
	if (pParent)
		pParent->Remove(pObject);

	pObject = object;

	if (pParent && object)
		pParent->Add(pObject);
}

INLINE void Timeline::SetParent(Movie *parent)
{
	if (pParent)
		pParent->Remove(pObject);

	pParent = parent;

	if (parent && pObject)
		parent->Add(pObject);
}

INLINE Movie *Timeline::GetParent() const
{
	return pParent;
}

} // namespace
<|endoftext|>


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

#include "registry/version.h"
#include "registry/writer.hxx"

using namespace ::rtl;

AstInterface::AstInterface(const ::rtl::OString& name,
                           AstInterface const * pInherits,
                           AstScope* pScope)
    : AstType(NT_interface, name, pScope)
    , AstScope(NT_interface)
    , m_mandatoryInterfaces(0)
    , m_bIsDefined(false)
    , m_bForwarded(sal_False)
    , m_bForwardedInSameFile(sal_False)
    , m_bSingleInheritance(pInherits != 0)
{
    if (pInherits != 0) {
        addInheritedInterface(pInherits, false, rtl::OUString());
    }
}

AstInterface::~AstInterface()
{
}

AstInterface::DoubleDeclarations AstInterface::checkInheritedInterfaceClashes(
    AstInterface const * ifc, bool optional) const
{
    DoubleDeclarations doubleDecls;
    std::set< rtl::OString > seen;
    checkInheritedInterfaceClashes(
        doubleDecls, seen, ifc, true, optional, optional);
    return doubleDecls;
}

void AstInterface::addInheritedInterface(
    AstInterface const * ifc, bool optional,
    rtl::OUString const & documentation)
{
    m_inheritedInterfaces.push_back(
        InheritedInterface(ifc, optional, documentation));
    if (!optional) {
        ++m_mandatoryInterfaces;
    }
    addVisibleInterface(ifc, true, optional);
    if (optional) {
        addOptionalVisibleMembers(ifc);
    }
}

AstInterface::DoubleMemberDeclarations AstInterface::checkMemberClashes(
    AstDeclaration const * member) const
{
    DoubleMemberDeclarations doubleMembers;
    checkMemberClashes(doubleMembers, member, true);
    return doubleMembers;
}

void AstInterface::addMember(AstDeclaration /*TODO: const*/ * member) {
    addDeclaration(member);
    m_visibleMembers.insert(
        VisibleMembers::value_type(
            member->getLocalName(), VisibleMember(member)));
}

void AstInterface::forwardDefined(AstInterface const & def)
{
    setImported(def.isImported());
    setInMainfile(def.isInMainfile());
    setLineNumber(def.getLineNumber());
    setFileName(def.getFileName());
    setDocumentation(def.getDocumentation());
    m_inheritedInterfaces = def.m_inheritedInterfaces;
    m_mandatoryInterfaces = def.m_mandatoryInterfaces;
    m_bIsDefined = true;
}

sal_Bool AstInterface::dump(RegistryKey& rKey)
{
    if ( !isDefined() )
        return sal_True;

    RegistryKey localKey;
    if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey))
    {
        fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return sal_False;
    }

    if (m_mandatoryInterfaces > SAL_MAX_UINT16
        || m_inheritedInterfaces.size() - m_mandatoryInterfaces
            > SAL_MAX_UINT16)
    {
        fprintf(
            stderr, "%s: interface %s has too many direct base interfaces\n",
            idlc()->getOptions()->getProgramName().getStr(),
            getScopedName().getStr());
        return false;
    }
    sal_uInt16 nBaseTypes = static_cast< sal_uInt16 >(m_mandatoryInterfaces);
    sal_uInt16 nAttributes = 0;
    sal_uInt16 nMethods = 0;
    sal_uInt16 nReferences = static_cast< sal_uInt16 >(
        m_inheritedInterfaces.size() - m_mandatoryInterfaces);
    typereg_Version version = nBaseTypes <= 1 && nReferences == 0
        ? TYPEREG_VERSION_0 : TYPEREG_VERSION_1;
    {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
          ++i)
    {
        switch ((*i)->getNodeType()) {
        case NT_attribute:
            {
                if (!increment(&nAttributes, "attributes")) {
                    return false;
                }
                AstAttribute * attr = static_cast< AstAttribute * >(*i);
                if (attr->isBound()) {
                    version = TYPEREG_VERSION_1;
                }
                DeclList::size_type getCount = attr->getGetExceptionCount();
                if (getCount > SAL_MAX_UINT16) {
                    fprintf(
                        stderr,
                        ("%s: raises clause of getter for attribute %s of"
                         " interface %s is too long\n"),
                        idlc()->getOptions()->getProgramName().getStr(),
                        (*i)->getLocalName().getStr(),
                        getScopedName().getStr());
                    return false;
                }
                if (getCount > 0) {
                    version = TYPEREG_VERSION_1;
                    if (!increment(&nMethods, "attributes")) {
                        return false;
                    }
                }
                DeclList::size_type setCount = attr->getSetExceptionCount();
                if (setCount > SAL_MAX_UINT16) {
                    fprintf(
                        stderr,
                        ("%s: raises clause of setter for attribute %s of"
                         " interface %s is too long\n"),
                        idlc()->getOptions()->getProgramName().getStr(),
                        (*i)->getLocalName().getStr(),
                        getScopedName().getStr());
                    return false;
                }
                if (setCount > 0) {
                    version = TYPEREG_VERSION_1;
                    if (!increment(&nMethods, "attributes")) {
                        return false;
                    }
                }
                break;
            }

        case NT_operation:
            if (!increment(&nMethods, "methods")) {
                return false;
            }
            break;

        default:
            OSL_ASSERT(false);
            break;
        }
    }}

    typereg::Writer aBlob(
        version, getDocumentation(),
        OStringToOUString(getFileName(), RTL_TEXTENCODING_UTF8),
        RT_TYPE_INTERFACE,
        OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), nBaseTypes,
        nAttributes, nMethods, nReferences);

    sal_uInt16 superTypeIndex = 0;
    sal_uInt16 referenceIndex = 0;
    {for (InheritedInterfaces::iterator i = m_inheritedInterfaces.begin();
          i != m_inheritedInterfaces.end(); ++i)
    {
        if (i->isOptional()) {
            aBlob.setReferenceData(
                referenceIndex++, i->getDocumentation(), RT_REF_SUPPORTS,
                RT_ACCESS_OPTIONAL,
                OStringToOUString(
                    i->getInterface()->getRelativName(),
                    RTL_TEXTENCODING_UTF8));
        } else {
            aBlob.setSuperTypeName(
                superTypeIndex++,
                OStringToOUString(
                    i->getInterface()->getRelativName(),
                    RTL_TEXTENCODING_UTF8));
        }
    }}

    sal_uInt16 attributeIndex = 0;
    sal_uInt16 methodIndex = 0;
    {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
          ++i)
    {
        switch ((*i)->getNodeType()) {
        case NT_attribute:
            static_cast< AstAttribute * >(*i)->dumpBlob(
                aBlob, attributeIndex++, &methodIndex);
            break;

        case NT_operation:
            static_cast< AstOperation * >(*i)->dumpBlob(aBlob, methodIndex++);
            break;

        default:
            OSL_ASSERT(false);
            break;
        }
    }}

    sal_uInt32 aBlobSize;
    void const * pBlob = aBlob.getBlob(&aBlobSize);

    if (localKey.setValue(
            OUString(), RG_VALUETYPE_BINARY, (RegValue)pBlob, aBlobSize))
    {
        fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return sal_False;
    }

    return true;
}

void AstInterface::checkInheritedInterfaceClashes(
    DoubleDeclarations & doubleDeclarations,
    std::set< rtl::OString > & seenInterfaces, AstInterface const * ifc,
    bool direct, bool optional, bool mainOptional) const
{
    if (direct || optional
        || seenInterfaces.insert(ifc->getScopedName()).second)
    {
        VisibleInterfaces::const_iterator visible(
            m_visibleInterfaces.find(ifc->getScopedName()));
        if (visible != m_visibleInterfaces.end()) {
            switch (visible->second) {
            case INTERFACE_INDIRECT_OPTIONAL:
                if (direct && optional) {
                    doubleDeclarations.interfaces.push_back(ifc);
                    return;
                }
                break;

            case INTERFACE_DIRECT_OPTIONAL:
                if (direct || !mainOptional) {
                    doubleDeclarations.interfaces.push_back(ifc);
                }
                return;

            case INTERFACE_INDIRECT_MANDATORY:
                if (direct) {
                    doubleDeclarations.interfaces.push_back(ifc);
                }
                return;

            case INTERFACE_DIRECT_MANDATORY:
                if (direct || !optional && !mainOptional) {
                    doubleDeclarations.interfaces.push_back(ifc);
                }
                return;
            }
        }
        if (direct || !optional) {
            {for (DeclList::const_iterator i(ifc->getIteratorBegin());
                  i != ifc->getIteratorEnd(); ++i)
            {
                checkMemberClashes(
                    doubleDeclarations.members, *i, !mainOptional);
            }}
            {for (InheritedInterfaces::const_iterator i(
                      ifc->m_inheritedInterfaces.begin());
                  i != ifc->m_inheritedInterfaces.end(); ++i)
            {
                checkInheritedInterfaceClashes(
                    doubleDeclarations, seenInterfaces, i->getInterface(),
                    false, i->isOptional(), mainOptional);
            }}
        }
    }
}

void AstInterface::checkMemberClashes(
    DoubleMemberDeclarations & doubleMembers, AstDeclaration const * member,
    bool checkOptional) const
{
    VisibleMembers::const_iterator i(
        m_visibleMembers.find(member->getLocalName()));
    if (i != m_visibleMembers.end()) {
        if (i->second.mandatory != 0) {
            if (i->second.mandatory->getScopedName() != member->getScopedName())
            {
                DoubleMemberDeclaration d;
                d.first = i->second.mandatory;
                d.second = member;
                doubleMembers.push_back(d);
            }
        } else if (checkOptional) {
            for (VisibleMember::Optionals::const_iterator j(
                     i->second.optionals.begin());
                 j != i->second.optionals.end(); ++j)
            {
                if (j->second->getScopedName() != member->getScopedName()) {
                    DoubleMemberDeclaration d;
                    d.first = j->second;
                    d.second = member;
                    doubleMembers.push_back(d);
                }
            }
        }
    }
}

void AstInterface::addVisibleInterface(
    AstInterface const * ifc, bool direct, bool optional)
{
    InterfaceKind kind = optional
        ? direct ? INTERFACE_DIRECT_OPTIONAL : INTERFACE_INDIRECT_OPTIONAL
        : direct ? INTERFACE_DIRECT_MANDATORY : INTERFACE_INDIRECT_MANDATORY;
    std::pair< VisibleInterfaces::iterator, bool > result(
        m_visibleInterfaces.insert(
            VisibleInterfaces::value_type(ifc->getScopedName(), kind)));
    bool seen = !result.second
        && result.first->second >= INTERFACE_INDIRECT_MANDATORY;
    if (!result.second && kind > result.first->second) {
        result.first->second = kind;
    }
    if (!optional && !seen) {
        {for (DeclList::const_iterator i(ifc->getIteratorBegin());
              i != ifc->getIteratorEnd(); ++i)
        {
            m_visibleMembers.insert(
                VisibleMembers::value_type(
                    (*i)->getLocalName(), VisibleMember(*i)));
        }}
        {for (InheritedInterfaces::const_iterator i(
                  ifc->m_inheritedInterfaces.begin());
              i != ifc->m_inheritedInterfaces.end(); ++i)
        {
            addVisibleInterface(i->getInterface(), false, i->isOptional());
        }}
    }
}

void AstInterface::addOptionalVisibleMembers(AstInterface const * ifc) {
    {for (DeclList::const_iterator i(ifc->getIteratorBegin());
          i != ifc->getIteratorEnd(); ++i)
    {
        VisibleMembers::iterator visible(
            m_visibleMembers.find((*i)->getLocalName()));
        if (visible == m_visibleMembers.end()) {
            visible = m_visibleMembers.insert(
                VisibleMembers::value_type(
                    (*i)->getLocalName(), VisibleMember())).first;
        }
        if (visible->second.mandatory == 0) {
            visible->second.optionals.insert(
                VisibleMember::Optionals::value_type(ifc->getScopedName(), *i));
        }
    }}
    {for (InheritedInterfaces::const_iterator i(
              ifc->m_inheritedInterfaces.begin());
          i != ifc->m_inheritedInterfaces.end(); ++i)
    {
        if (!i->isOptional()) {
            addOptionalVisibleMembers(i->getInterface());
        }
    }}
}

bool AstInterface::increment(sal_uInt16 * counter, char const * sort) const {
    if (*counter == SAL_MAX_UINT16) {
        fprintf(
            stderr, "%s: interface %s has too many direct %s\n",
            idlc()->getOptions()->getProgramName().getStr(),
            getScopedName().getStr(), sort);
        return false;
    }
    ++*counter;
    return true;
}
<commit_msg>INTEGRATION: CWS sb18 (1.5.4); FILE MERGED 2004/05/18 15:36:49 sb 1.5.4.2: #i21150# Added new feature: published. 2004/04/08 14:37:16 sb 1.5.4.1: #i21150# Fixed UNOIDL typedef support; initial support for polymorphic struct types.<commit_after>/*************************************************************************
 *
 *  $RCSfile: astinterface.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2004-06-03 15:08:24 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _IDLC_ASTINTERFACE_HXX_
#include <idlc/astinterface.hxx>
#endif
#ifndef _IDLC_ASTATTRIBUTE_HXX_
#include <idlc/astattribute.hxx>
#endif
#ifndef _IDLC_ASTOPERATION_HXX_
#include <idlc/astoperation.hxx>
#endif
#include "idlc/idlc.hxx"

#include "registry/version.h"
#include "registry/writer.hxx"

using namespace ::rtl;

AstInterface::AstInterface(const ::rtl::OString& name,
                           AstInterface const * pInherits,
                           AstScope* pScope)
    : AstType(NT_interface, name, pScope)
    , AstScope(NT_interface)
    , m_mandatoryInterfaces(0)
    , m_bIsDefined(false)
    , m_bForwarded(sal_False)
    , m_bForwardedInSameFile(sal_False)
    , m_bSingleInheritance(pInherits != 0)
{
    if (pInherits != 0) {
        addInheritedInterface(pInherits, false, rtl::OUString());
    }
}

AstInterface::~AstInterface()
{
}

AstInterface::DoubleDeclarations AstInterface::checkInheritedInterfaceClashes(
    AstInterface const * ifc, bool optional) const
{
    DoubleDeclarations doubleDecls;
    std::set< rtl::OString > seen;
    checkInheritedInterfaceClashes(
        doubleDecls, seen, ifc, true, optional, optional);
    return doubleDecls;
}

void AstInterface::addInheritedInterface(
    AstType const * ifc, bool optional, rtl::OUString const & documentation)
{
    m_inheritedInterfaces.push_back(
        InheritedInterface(ifc, optional, documentation));
    if (!optional) {
        ++m_mandatoryInterfaces;
    }
    AstInterface const * resolved = resolveInterfaceTypedefs(ifc);
    addVisibleInterface(resolved, true, optional);
    if (optional) {
        addOptionalVisibleMembers(resolved);
    }
}

AstInterface::DoubleMemberDeclarations AstInterface::checkMemberClashes(
    AstDeclaration const * member) const
{
    DoubleMemberDeclarations doubleMembers;
    checkMemberClashes(doubleMembers, member, true);
    return doubleMembers;
}

void AstInterface::addMember(AstDeclaration /*TODO: const*/ * member) {
    addDeclaration(member);
    m_visibleMembers.insert(
        VisibleMembers::value_type(
            member->getLocalName(), VisibleMember(member)));
}

void AstInterface::forwardDefined(AstInterface const & def)
{
    setImported(def.isImported());
    setInMainfile(def.isInMainfile());
    setLineNumber(def.getLineNumber());
    setFileName(def.getFileName());
    setDocumentation(def.getDocumentation());
    m_inheritedInterfaces = def.m_inheritedInterfaces;
    m_mandatoryInterfaces = def.m_mandatoryInterfaces;
    m_bIsDefined = true;
}

sal_Bool AstInterface::dump(RegistryKey& rKey)
{
    if ( !isDefined() )
        return sal_True;

    RegistryKey localKey;
    if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey))
    {
        fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return sal_False;
    }

    if (m_mandatoryInterfaces > SAL_MAX_UINT16
        || m_inheritedInterfaces.size() - m_mandatoryInterfaces
            > SAL_MAX_UINT16)
    {
        fprintf(
            stderr, "%s: interface %s has too many direct base interfaces\n",
            idlc()->getOptions()->getProgramName().getStr(),
            getScopedName().getStr());
        return false;
    }
    sal_uInt16 nBaseTypes = static_cast< sal_uInt16 >(m_mandatoryInterfaces);
    sal_uInt16 nAttributes = 0;
    sal_uInt16 nMethods = 0;
    sal_uInt16 nReferences = static_cast< sal_uInt16 >(
        m_inheritedInterfaces.size() - m_mandatoryInterfaces);
    typereg_Version version
        = (nBaseTypes <= 1 && nReferences == 0 && !m_bPublished
           ? TYPEREG_VERSION_0 : TYPEREG_VERSION_1);
    {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
          ++i)
    {
        switch ((*i)->getNodeType()) {
        case NT_attribute:
            {
                if (!increment(&nAttributes, "attributes")) {
                    return false;
                }
                AstAttribute * attr = static_cast< AstAttribute * >(*i);
                if (attr->isBound()) {
                    version = TYPEREG_VERSION_1;
                }
                DeclList::size_type getCount = attr->getGetExceptionCount();
                if (getCount > SAL_MAX_UINT16) {
                    fprintf(
                        stderr,
                        ("%s: raises clause of getter for attribute %s of"
                         " interface %s is too long\n"),
                        idlc()->getOptions()->getProgramName().getStr(),
                        (*i)->getLocalName().getStr(),
                        getScopedName().getStr());
                    return false;
                }
                if (getCount > 0) {
                    version = TYPEREG_VERSION_1;
                    if (!increment(&nMethods, "attributes")) {
                        return false;
                    }
                }
                DeclList::size_type setCount = attr->getSetExceptionCount();
                if (setCount > SAL_MAX_UINT16) {
                    fprintf(
                        stderr,
                        ("%s: raises clause of setter for attribute %s of"
                         " interface %s is too long\n"),
                        idlc()->getOptions()->getProgramName().getStr(),
                        (*i)->getLocalName().getStr(),
                        getScopedName().getStr());
                    return false;
                }
                if (setCount > 0) {
                    version = TYPEREG_VERSION_1;
                    if (!increment(&nMethods, "attributes")) {
                        return false;
                    }
                }
                break;
            }

        case NT_operation:
            if (!increment(&nMethods, "methods")) {
                return false;
            }
            break;

        default:
            OSL_ASSERT(false);
            break;
        }
    }}

    typereg::Writer aBlob(
        version, getDocumentation(),
        OStringToOUString(getFileName(), RTL_TEXTENCODING_UTF8),
        RT_TYPE_INTERFACE, m_bPublished,
        OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), nBaseTypes,
        nAttributes, nMethods, nReferences);

    sal_uInt16 superTypeIndex = 0;
    sal_uInt16 referenceIndex = 0;
    {for (InheritedInterfaces::iterator i = m_inheritedInterfaces.begin();
          i != m_inheritedInterfaces.end(); ++i)
    {
        if (i->isOptional()) {
            aBlob.setReferenceData(
                referenceIndex++, i->getDocumentation(), RT_REF_SUPPORTS,
                RT_ACCESS_OPTIONAL,
                OStringToOUString(
                    i->getInterface()->getRelativName(),
                    RTL_TEXTENCODING_UTF8));
        } else {
            aBlob.setSuperTypeName(
                superTypeIndex++,
                OStringToOUString(
                    i->getInterface()->getRelativName(),
                    RTL_TEXTENCODING_UTF8));
        }
    }}

    sal_uInt16 attributeIndex = 0;
    sal_uInt16 methodIndex = 0;
    {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
          ++i)
    {
        switch ((*i)->getNodeType()) {
        case NT_attribute:
            static_cast< AstAttribute * >(*i)->dumpBlob(
                aBlob, attributeIndex++, &methodIndex);
            break;

        case NT_operation:
            static_cast< AstOperation * >(*i)->dumpBlob(aBlob, methodIndex++);
            break;

        default:
            OSL_ASSERT(false);
            break;
        }
    }}

    sal_uInt32 aBlobSize;
    void const * pBlob = aBlob.getBlob(&aBlobSize);

    if (localKey.setValue(
            OUString(), RG_VALUETYPE_BINARY, (RegValue)pBlob, aBlobSize))
    {
        fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
                idlc()->getOptions()->getProgramName().getStr(),
                getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
        return sal_False;
    }

    return true;
}

void AstInterface::checkInheritedInterfaceClashes(
    DoubleDeclarations & doubleDeclarations,
    std::set< rtl::OString > & seenInterfaces, AstInterface const * ifc,
    bool direct, bool optional, bool mainOptional) const
{
    if (direct || optional
        || seenInterfaces.insert(ifc->getScopedName()).second)
    {
        VisibleInterfaces::const_iterator visible(
            m_visibleInterfaces.find(ifc->getScopedName()));
        if (visible != m_visibleInterfaces.end()) {
            switch (visible->second) {
            case INTERFACE_INDIRECT_OPTIONAL:
                if (direct && optional) {
                    doubleDeclarations.interfaces.push_back(ifc);
                    return;
                }
                break;

            case INTERFACE_DIRECT_OPTIONAL:
                if (direct || !mainOptional) {
                    doubleDeclarations.interfaces.push_back(ifc);
                }
                return;

            case INTERFACE_INDIRECT_MANDATORY:
                if (direct) {
                    doubleDeclarations.interfaces.push_back(ifc);
                }
                return;

            case INTERFACE_DIRECT_MANDATORY:
                if (direct || !optional && !mainOptional) {
                    doubleDeclarations.interfaces.push_back(ifc);
                }
                return;
            }
        }
        if (direct || !optional) {
            {for (DeclList::const_iterator i(ifc->getIteratorBegin());
                  i != ifc->getIteratorEnd(); ++i)
            {
                checkMemberClashes(
                    doubleDeclarations.members, *i, !mainOptional);
            }}
            {for (InheritedInterfaces::const_iterator i(
                      ifc->m_inheritedInterfaces.begin());
                  i != ifc->m_inheritedInterfaces.end(); ++i)
            {
                checkInheritedInterfaceClashes(
                    doubleDeclarations, seenInterfaces, i->getResolved(),
                    false, i->isOptional(), mainOptional);
            }}
        }
    }
}

void AstInterface::checkMemberClashes(
    DoubleMemberDeclarations & doubleMembers, AstDeclaration const * member,
    bool checkOptional) const
{
    VisibleMembers::const_iterator i(
        m_visibleMembers.find(member->getLocalName()));
    if (i != m_visibleMembers.end()) {
        if (i->second.mandatory != 0) {
            if (i->second.mandatory->getScopedName() != member->getScopedName())
            {
                DoubleMemberDeclaration d;
                d.first = i->second.mandatory;
                d.second = member;
                doubleMembers.push_back(d);
            }
        } else if (checkOptional) {
            for (VisibleMember::Optionals::const_iterator j(
                     i->second.optionals.begin());
                 j != i->second.optionals.end(); ++j)
            {
                if (j->second->getScopedName() != member->getScopedName()) {
                    DoubleMemberDeclaration d;
                    d.first = j->second;
                    d.second = member;
                    doubleMembers.push_back(d);
                }
            }
        }
    }
}

void AstInterface::addVisibleInterface(
    AstInterface const * ifc, bool direct, bool optional)
{
    InterfaceKind kind = optional
        ? direct ? INTERFACE_DIRECT_OPTIONAL : INTERFACE_INDIRECT_OPTIONAL
        : direct ? INTERFACE_DIRECT_MANDATORY : INTERFACE_INDIRECT_MANDATORY;
    std::pair< VisibleInterfaces::iterator, bool > result(
        m_visibleInterfaces.insert(
            VisibleInterfaces::value_type(ifc->getScopedName(), kind)));
    bool seen = !result.second
        && result.first->second >= INTERFACE_INDIRECT_MANDATORY;
    if (!result.second && kind > result.first->second) {
        result.first->second = kind;
    }
    if (!optional && !seen) {
        {for (DeclList::const_iterator i(ifc->getIteratorBegin());
              i != ifc->getIteratorEnd(); ++i)
        {
            m_visibleMembers.insert(
                VisibleMembers::value_type(
                    (*i)->getLocalName(), VisibleMember(*i)));
        }}
        {for (InheritedInterfaces::const_iterator i(
                  ifc->m_inheritedInterfaces.begin());
              i != ifc->m_inheritedInterfaces.end(); ++i)
        {
            addVisibleInterface(i->getResolved(), false, i->isOptional());
        }}
    }
}

void AstInterface::addOptionalVisibleMembers(AstInterface const * ifc) {
    {for (DeclList::const_iterator i(ifc->getIteratorBegin());
          i != ifc->getIteratorEnd(); ++i)
    {
        VisibleMembers::iterator visible(
            m_visibleMembers.find((*i)->getLocalName()));
        if (visible == m_visibleMembers.end()) {
            visible = m_visibleMembers.insert(
                VisibleMembers::value_type(
                    (*i)->getLocalName(), VisibleMember())).first;
        }
        if (visible->second.mandatory == 0) {
            visible->second.optionals.insert(
                VisibleMember::Optionals::value_type(ifc->getScopedName(), *i));
        }
    }}
    {for (InheritedInterfaces::const_iterator i(
              ifc->m_inheritedInterfaces.begin());
          i != ifc->m_inheritedInterfaces.end(); ++i)
    {
        if (!i->isOptional()) {
            addOptionalVisibleMembers(i->getResolved());
        }
    }}
}

bool AstInterface::increment(sal_uInt16 * counter, char const * sort) const {
    if (*counter == SAL_MAX_UINT16) {
        fprintf(
            stderr, "%s: interface %s has too many direct %s\n",
            idlc()->getOptions()->getProgramName().getStr(),
            getScopedName().getStr(), sort);
        return false;
    }
    ++*counter;
    return true;
}
<|endoftext|>


<commit_before>// Example macro to use chi2 test
// One unweighted histogram is compared with a weighted histogram.
// The normalized residuals are retrieved and plotted in a simple graph.
// The QQ plot of the normalized residual using the
// normal distribution is also plotted.
//
//Authors: Nikolai Gagunashvili, Daniel Haertl, Lorenzo Moneta

#include "TH1.h"
#include "TH1D.h"
#include "TF1.h"
#include "TGraph.h"
#include "TGraphQQ.h"
#include "TCanvas.h"
#include "TStyle.h"
#include "TMath.h"

TCanvas * chi2test(Float_t w=0)
{

  //Define Histograms

  const Int_t n = 20;

  TH1D *h1 = new TH1D("h1", "h1", n, 4, 16);
  TH1D *h2 = new TH1D("h2", "h2", n, 4, 16);

  h1->SetTitle("Unweighted Histogram");
  h2->SetTitle("Weighted Histogram");

  h1->SetBinContent(1, 0);
  h1->SetBinContent(2, 1);
  h1->SetBinContent(3, 0);
  h1->SetBinContent(4, 1);
  h1->SetBinContent(5, 1);
  h1->SetBinContent(6, 6);
  h1->SetBinContent(7, 7);
  h1->SetBinContent(8, 2);
  h1->SetBinContent(9, 22);
  h1->SetBinContent(10, 30);
  h1->SetBinContent(11, 27);
  h1->SetBinContent(12, 20);
  h1->SetBinContent(13, 13);
  h1->SetBinContent(14, 9);
  h1->SetBinContent(15, 9+w);
  h1->SetBinContent(16, 13);
  h1->SetBinContent(17, 19);
  h1->SetBinContent(18, 11);
  h1->SetBinContent(19, 9);
  h1->SetBinContent(20, 0);
  h1->SetBinError(1, 0);
  h1->SetBinError(2, 1);
  h1->SetBinError(3, 0);
  h1->SetBinError(4, 1);
  h1->SetBinError(5, 1);
  h1->SetBinError(6, 2.44948983);
  h1->SetBinError(7, 2.64575124 );
  h1->SetBinError(8, 1.41421354);
  h1->SetBinError(9, 4.69041586);
  h1->SetBinError(10, 5.47722578);
  h1->SetBinError(11, 5.19615221);
  h1->SetBinError(12, 4.47213602);
  h1->SetBinError(13, 3.60555124);
  h1->SetBinError(14, 3.);
  h1->SetBinError(15, 5.38516474);
  h1->SetBinError(16, 3.60555124);
  h1->SetBinError(17, 4.35889912);
  h1->SetBinError(18, 3.31662488);
  h1->SetBinError(19, 3.);
  h1->SetBinError(20, 0);
  h2->SetBinContent(1, 2.20173025 );
  h2->SetBinContent(2, 3.30143857);
  h2->SetBinContent(3, 2.5892849);
  h2->SetBinContent(4, 2.99990201);
  h2->SetBinContent(5, 4.92877054);
  h2->SetBinContent(6, 8.33036995);
  h2->SetBinContent(7, 6.95084763);
  h2->SetBinContent(8, 15.206357);
  h2->SetBinContent(9, 23.9236012);
  h2->SetBinContent(10, 44.3848114);
  h2->SetBinContent(11, 49.4465599);
  h2->SetBinContent(12, 25.1868858);
  h2->SetBinContent(13, 16.3129692);
  h2->SetBinContent(14, 13.0289612);
  h2->SetBinContent(15, 16.7857609);
  h2->SetBinContent(16, 22.9914703);
  h2->SetBinContent(17, 30.5279255);
  h2->SetBinContent(18, 12.5252123);
  h2->SetBinContent(19, 16.4104557);
  h2->SetBinContent(20, 7.86067867);
  h2->SetBinError(1, 0.38974303 );
  h2->SetBinError(2, 0.536510944);
  h2->SetBinError(3, 0.529702604);
  h2->SetBinError(4, 0.642001867);
  h2->SetBinError(5, 0.969341516);
  h2->SetBinError(6, 1.47611344);
  h2->SetBinError(7, 1.69797957);
  h2->SetBinError(8, 3.28577447);
  h2->SetBinError(9, 5.40784931);
  h2->SetBinError(10, 9.10106468);
  h2->SetBinError(11, 9.73541737);
  h2->SetBinError(12, 5.55019951);
  h2->SetBinError(13, 3.57914758);
  h2->SetBinError(14, 2.77877331);
  h2->SetBinError(15, 3.23697519);
  h2->SetBinError(16, 4.3608489);
  h2->SetBinError(17, 5.77172089);
  h2->SetBinError(18, 3.38666105);
  h2->SetBinError(19, 2.98861837);
  h2->SetBinError(20, 1.58402085);

  h1->SetEntries(217);
  h2->SetEntries(500);

//apply the chi2 test and retrieve the residuals
  Double_t res[n], x[n];
  h1->Chi2Test(h2,"UW P",res);

//Graph for Residuals
  for (Int_t i=0; i<n; i++) x[i]= 4.+i*12./20.+12./40.;
  TGraph *resgr = new TGraph(n,x,res);
  resgr->GetXaxis()->SetRangeUser(4,16);
  resgr->GetYaxis()->SetRangeUser(-3.5,3.5);
  resgr->GetYaxis()->SetTitle("Normalized Residuals");
  resgr->SetMarkerStyle(21);
  resgr->SetMarkerColor(2);
  resgr->SetMarkerSize(.9);
  resgr->SetTitle("Normalized Residuals");

//Quantile-Quantile plot
  TF1 *f = new TF1("f","TMath::Gaus(x,0,1)",-10,10);
  TGraphQQ *qqplot = new TGraphQQ(n,res,f);
  qqplot->SetMarkerStyle(20);
  qqplot->SetMarkerColor(2);
  qqplot->SetMarkerSize(.9);
  qqplot->SetTitle("Q-Q plot of Normalized Residuals");

//create Canvas
  TCanvas *c1 = new TCanvas("c1","Chistat Plot",10,10,700,600);
  c1->SetFillColor(33);
  c1->Divide(2,2);

// Draw Histogramms and Graphs
  c1->cd(1);
  gPad->SetFrameFillColor(21);
  h1->SetMarkerColor(4);
  h1->SetMarkerStyle(20);

  h1->Draw("E");

  c1->cd(2);
  gPad->SetFrameFillColor(21);
  h2->Draw("");
  h2->SetMarkerColor(4);
  h2->SetMarkerStyle(20);

  c1->cd(3);
  gPad->SetFrameFillColor(21);
  gPad->SetGridy();
  resgr->Draw("APL");

  c1->cd(4);
  gPad->SetFrameFillColor(21);
  qqplot->Draw("AP");

  c1->cd(0);

  c1->Update();
   return c1;
}
<commit_msg>- Add comments<commit_after>// Example macro to use chi2 test
// One unweighted histogram is compared with a weighted histogram.
// The normalized residuals are retrieved and plotted in a simple graph.
// The QQ plot of the normalized residual using the
// normal distribution is also plotted.
//
//Authors: Nikolai Gagunashvili, Daniel Haertl, Lorenzo Moneta

#include "TH1.h"
#include "TH1D.h"
#include "TF1.h"
#include "TGraph.h"
#include "TGraphQQ.h"
#include "TCanvas.h"
#include "TStyle.h"
#include "TMath.h"

TCanvas * chi2test(Float_t w=0)
{
  // Note: The parameter w is used to produce the 2 pictures in
  // the TH1::Chi2Test method. The 1st picture is produced with
  // w=0 and the 2nd with w=17 (see TH1::Chi2Test() help).

  // Define Histograms.
  const Int_t n = 20;

  TH1D *h1 = new TH1D("h1", "h1", n, 4, 16);
  TH1D *h2 = new TH1D("h2", "h2", n, 4, 16);

  h1->SetTitle("Unweighted Histogram");
  h2->SetTitle("Weighted Histogram");

  h1->SetBinContent(1, 0);
  h1->SetBinContent(2, 1);
  h1->SetBinContent(3, 0);
  h1->SetBinContent(4, 1);
  h1->SetBinContent(5, 1);
  h1->SetBinContent(6, 6);
  h1->SetBinContent(7, 7);
  h1->SetBinContent(8, 2);
  h1->SetBinContent(9, 22);
  h1->SetBinContent(10, 30);
  h1->SetBinContent(11, 27);
  h1->SetBinContent(12, 20);
  h1->SetBinContent(13, 13);
  h1->SetBinContent(14, 9);
  h1->SetBinContent(15, 9+w);
  h1->SetBinContent(16, 13);
  h1->SetBinContent(17, 19);
  h1->SetBinContent(18, 11);
  h1->SetBinContent(19, 9);
  h1->SetBinContent(20, 0);
  h1->SetBinError(1, 0);
  h1->SetBinError(2, 1);
  h1->SetBinError(3, 0);
  h1->SetBinError(4, 1);
  h1->SetBinError(5, 1);
  h1->SetBinError(6, 2.44948983);
  h1->SetBinError(7, 2.64575124 );
  h1->SetBinError(8, 1.41421354);
  h1->SetBinError(9, 4.69041586);
  h1->SetBinError(10, 5.47722578);
  h1->SetBinError(11, 5.19615221);
  h1->SetBinError(12, 4.47213602);
  h1->SetBinError(13, 3.60555124);
  h1->SetBinError(14, 3.);
  h1->SetBinError(15, 5.38516474);
  h1->SetBinError(16, 3.60555124);
  h1->SetBinError(17, 4.35889912);
  h1->SetBinError(18, 3.31662488);
  h1->SetBinError(19, 3.);
  h1->SetBinError(20, 0);
  h2->SetBinContent(1, 2.20173025 );
  h2->SetBinContent(2, 3.30143857);
  h2->SetBinContent(3, 2.5892849);
  h2->SetBinContent(4, 2.99990201);
  h2->SetBinContent(5, 4.92877054);
  h2->SetBinContent(6, 8.33036995);
  h2->SetBinContent(7, 6.95084763);
  h2->SetBinContent(8, 15.206357);
  h2->SetBinContent(9, 23.9236012);
  h2->SetBinContent(10, 44.3848114);
  h2->SetBinContent(11, 49.4465599);
  h2->SetBinContent(12, 25.1868858);
  h2->SetBinContent(13, 16.3129692);
  h2->SetBinContent(14, 13.0289612);
  h2->SetBinContent(15, 16.7857609);
  h2->SetBinContent(16, 22.9914703);
  h2->SetBinContent(17, 30.5279255);
  h2->SetBinContent(18, 12.5252123);
  h2->SetBinContent(19, 16.4104557);
  h2->SetBinContent(20, 7.86067867);
  h2->SetBinError(1, 0.38974303 );
  h2->SetBinError(2, 0.536510944);
  h2->SetBinError(3, 0.529702604);
  h2->SetBinError(4, 0.642001867);
  h2->SetBinError(5, 0.969341516);
  h2->SetBinError(6, 1.47611344);
  h2->SetBinError(7, 1.69797957);
  h2->SetBinError(8, 3.28577447);
  h2->SetBinError(9, 5.40784931);
  h2->SetBinError(10, 9.10106468);
  h2->SetBinError(11, 9.73541737);
  h2->SetBinError(12, 5.55019951);
  h2->SetBinError(13, 3.57914758);
  h2->SetBinError(14, 2.77877331);
  h2->SetBinError(15, 3.23697519);
  h2->SetBinError(16, 4.3608489);
  h2->SetBinError(17, 5.77172089);
  h2->SetBinError(18, 3.38666105);
  h2->SetBinError(19, 2.98861837);
  h2->SetBinError(20, 1.58402085);

  h1->SetEntries(217);
  h2->SetEntries(500);

//apply the chi2 test and retrieve the residuals
  Double_t res[n], x[n];
  h1->Chi2Test(h2,"UW P",res);

//Graph for Residuals
  for (Int_t i=0; i<n; i++) x[i]= 4.+i*12./20.+12./40.;
  TGraph *resgr = new TGraph(n,x,res);
  resgr->GetXaxis()->SetRangeUser(4,16);
  resgr->GetYaxis()->SetRangeUser(-3.5,3.5);
  resgr->GetYaxis()->SetTitle("Normalized Residuals");
  resgr->SetMarkerStyle(21);
  resgr->SetMarkerColor(2);
  resgr->SetMarkerSize(.9);
  resgr->SetTitle("Normalized Residuals");

//Quantile-Quantile plot
  TF1 *f = new TF1("f","TMath::Gaus(x,0,1)",-10,10);
  TGraphQQ *qqplot = new TGraphQQ(n,res,f);
  qqplot->SetMarkerStyle(20);
  qqplot->SetMarkerColor(2);
  qqplot->SetMarkerSize(.9);
  qqplot->SetTitle("Q-Q plot of Normalized Residuals");

//create Canvas
  TCanvas *c1 = new TCanvas("c1","Chistat Plot",10,10,700,600);
  c1->SetFillColor(33);
  c1->Divide(2,2);

// Draw Histogramms and Graphs
  c1->cd(1);
  gPad->SetFrameFillColor(21);
  h1->SetMarkerColor(4);
  h1->SetMarkerStyle(20);

  h1->Draw("E");

  c1->cd(2);
  gPad->SetFrameFillColor(21);
  h2->Draw("");
  h2->SetMarkerColor(4);
  h2->SetMarkerStyle(20);

  c1->cd(3);
  gPad->SetFrameFillColor(21);
  gPad->SetGridy();
  resgr->Draw("APL");

  c1->cd(4);
  gPad->SetFrameFillColor(21);
  qqplot->Draw("AP");

  c1->cd(0);

  c1->Update();
   return c1;
}
<|endoftext|>