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

#include <sys/stat.h>
#include <stdio.h>
#include <string.h>

#include "prj.hxx"

#include <string.hxx>
#include <list.hxx>
#include <fsys.hxx>
#include <stream.hxx>

#include "cppdep.hxx"

class RscHrcDep : public CppDep
{
public:
                    RscHrcDep();
    virtual         ~RscHrcDep();

    virtual void    Execute();
};

RscHrcDep::RscHrcDep()  :
    CppDep()
{
}

RscHrcDep::~RscHrcDep()
{
}

void RscHrcDep::Execute()
{
    CppDep::Execute();
}

//static String aDelim;

/* poor man's getopt() */
int     simple_getopt(int argc, char *argv[], const char *optstring);
#ifdef WNT
static char *optarg = NULL;
static int  optind = 1;
static int  optopt = 0;
static int  opterr = 0;
#endif

int
#ifdef WNT
_cdecl
#endif
main( int argc, char **argv )
{
    int c;
    int digit_optind = 0;
    char aBuf[255];
    char pOutputFileName[255];
    char pSrsFileName[255];
    String aSrsBaseName;
    BOOL bSource = FALSE;
    ByteString aRespArg;
    String aDelim = String(DirEntry::GetAccessDelimiter());

    RscHrcDep *pDep = new RscHrcDep;

    pOutputFileName[0] = 0;
    pSrsFileName[0] = 0;

    for ( int i=1; i<argc; i++)
    {
        strcpy( aBuf, (const char *)argv[i] );
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'o' && aBuf[3] == '=' )
        {
            strcpy(pOutputFileName, &aBuf[4]);
            //break;
        }
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'p' && aBuf[3] == '=' )
        {
            strcpy(pSrsFileName, &aBuf[4]);
            String aName( pSrsFileName, gsl_getSystemTextEncoding());
            USHORT nPos = 0;
            DirEntry aDest( aName );
            aSrsBaseName = aDest.GetBase();
            //break;
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'i' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'I' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '@' )
        {
            ByteString aToken;
            String aRespName( &aBuf[1], gsl_getSystemTextEncoding());
            SimpleConfig aConfig( aRespName );
            while ( (aToken = aConfig.GetNext()) != "")
            {
                char aBuf2[255];
                (void) strcpy( aBuf2, aToken.GetBuffer());
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'o' )
                {
                    strcpy(pOutputFileName, &aBuf2[3]);
                    //break;
                }
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'p' )
                {
                    strcpy(pSrsFileName, &aBuf2[3]);
                    String aName( pSrsFileName, gsl_getSystemTextEncoding());
                    USHORT nPos = 0;
                    DirEntry aDest( aName );
                    aSrsBaseName = aDest.GetBase();
                    //break;
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'i' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'I' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (( aBuf2[0] != '-' ) && ( aBuf2[0] != '@' ))
                {
                    pDep->AddSource( &aBuf2[0] );
                    aRespArg += " ";
                    aRespArg += &aBuf2[0];
                    bSource = TRUE;
                }
            }
        }
    }

    while( 1 )
    {
        int this_option_optind = optind ? optind : 1;
        c = simple_getopt( argc, argv,
        "_abcdefghi:jklmnopqrstuvwxyzABCDEFGHI:JKLMNOPQRSTUVWXYZ1234567890/-+=.\\()\"");
        if ( c == -1 )
            break;

        switch( c )
        {
            case 0:
                break;
            case 'a' :
#ifdef DEBUG_VERBOSE
                printf("option a\n");
#endif
                break;

            case 'l' :
#ifdef DEBUG_VERBOSE
                printf("option l with Value %s\n", optarg );
#endif
                pDep->AddSource( optarg );
                break;

            case 'h' :
            case 'H' :
            case '?' :
                printf("RscDep 1.0 (c)2000 StarOffice\n");
                break;

            default:
#ifdef DEBUG_VERBOSE
                printf("Unknown getopt error\n");
#endif
                ;
        }
    }

    DirEntry aEntry(".");
    aEntry.ToAbs();
    String aCwd = aEntry.GetName();
/*  USHORT nPos;
#ifndef UNX
    while ( (nPos = aCwd.Search('\\') != STRING_NOTFOUND  ))
#else
    while ( (nPos = aCwd.Search('/') != STRING_NOTFOUND  ))
#endif
    {
        String attt = aCwd.Copy( 0, nPos );
        aCwd.Erase( 0, nPos );
    } */
    SvFileStream aOutStream;
    String aOutputFileName( pOutputFileName, gsl_getSystemTextEncoding());
    DirEntry aOutEntry( aOutputFileName );
    String aOutPath = aOutEntry.GetPath().GetFull();

    String aFileName( aOutPath );
    aFileName += aDelim;
    aFileName += aCwd;
    aFileName += String(".", gsl_getSystemTextEncoding());
    aFileName += aSrsBaseName;
    aFileName += String(".dprr", gsl_getSystemTextEncoding());
    //fprintf( stderr, "OutFileName : %s \n",aFileName.GetStr());
    aOutStream.Open( aFileName, STREAM_WRITE );

    ByteString aString;
    if ( optind < argc )
    {
#ifdef DEBUG_VERBOSE
        printf("further arguments : ");
#endif
        aString = ByteString( pSrsFileName );
        aString += ByteString(" : " );

        while ( optind < argc )
        {
            if (!bSource )
            {
                aString += ByteString(" " );
                aString += ByteString( argv[optind]);
                pDep->AddSource( argv[optind++]);
            }
            else
            {
                optind++;
            }
        }
    }
    aString += aRespArg;
    pDep->Execute();
    ByteStringList *pLst = pDep->GetDepList();
    ULONG nCount = pLst->Count();
    if ( nCount == 0 )
    {
        aOutStream.WriteLine( aString );
    }
    else
    {
        aString += ByteString( "\\" );
        aOutStream.WriteLine( aString );
    }

    for ( ULONG j=0; j<nCount; j++ )
    {
        ByteString *pStr = pLst->GetObject(j);
#ifdef UNX
        pStr->SearchAndReplaceAll('\\', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
#ifdef WNT
        pStr->SearchAndReplaceAll('/', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
        if ( j != (nCount-1) )
            *pStr += ByteString( "\\" );
        aOutStream.WriteLine( *pStr );
    }
    delete pDep;
    aOutStream.Close();

    return 0;
}

/* my very simple minded implementation of getopt()
 * it's too sad that getopt() is not available everywhere
 * note: this is not a full POSIX conforming getopt()
 */
int simple_getopt(int argc, char *argv[], const char *optstring)
{
    char *arg = argv[optind];

    /* skip all response file arguments */
    if ( arg ) {
        while ( *arg == '@' )
            arg = argv[++optind];

        if ( arg[0] == '-' && arg[1] != '\0' ) {
            const char *popt;
            int c = arg[1];
            if ( (popt = strchr(optstring, c)) == NULL ) {
                optopt = c;
                if ( opterr )
                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
                return '?';
            }
            if ( *(++popt) == ':') {
                 if ( arg[2] != '\0' ) {
                     optarg = ++arg;
                 } else {
                     optarg = argv[++optind];
                 }
             } else {
                 optarg = NULL;
             }
             ++optind;
             return c;
        }
    }
    return -1;
}

<commit_msg>INTEGRATION: CWS warnings01 (1.20.8); FILE MERGED 2005/10/27 12:28:49 sb 1.20.8.2: #i53898# Made code warning-free. 2005/10/14 11:19:24 sb 1.20.8.1: #i53898# Made code warning-free; cleanup.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: rscdep.cxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 13:21:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifdef UNX
#include <unistd.h>
#endif

#include <sys/stat.h>
#include <stdio.h>
#include <string.h>

#include "bootstrp/prj.hxx"

#include <string.hxx>
#include <list.hxx>
#include <fsys.hxx>
#include <stream.hxx>

#include "cppdep.hxx"

class RscHrcDep : public CppDep
{
public:
                    RscHrcDep();
    virtual         ~RscHrcDep();

    virtual void    Execute();
};

RscHrcDep::RscHrcDep()  :
    CppDep()
{
}

RscHrcDep::~RscHrcDep()
{
}

void RscHrcDep::Execute()
{
    CppDep::Execute();
}

//static String aDelim;

/* poor man's getopt() */
int     simple_getopt(char *argv[], const char *optstring);
#ifdef WNT
static char *optarg = NULL;
static int  optind = 1;
static int  optopt = 0;
static int  opterr = 0;
#endif

int
#ifdef WNT
_cdecl
#endif
main( int argc, char **argv )
{
    int c;
    char aBuf[255];
    char pOutputFileName[255];
    char pSrsFileName[255];
    String aSrsBaseName;
    BOOL bSource = FALSE;
    ByteString aRespArg;
    String aDelim = String(DirEntry::GetAccessDelimiter());

    RscHrcDep *pDep = new RscHrcDep;

    pOutputFileName[0] = 0;
    pSrsFileName[0] = 0;

    for ( int i=1; i<argc; i++)
    {
        strcpy( aBuf, (const char *)argv[i] );
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'o' && aBuf[3] == '=' )
        {
            strcpy(pOutputFileName, &aBuf[4]);
            //break;
        }
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'p' && aBuf[3] == '=' )
        {
            strcpy(pSrsFileName, &aBuf[4]);
            String aName( pSrsFileName, gsl_getSystemTextEncoding());
            DirEntry aDest( aName );
            aSrsBaseName = aDest.GetBase();
            //break;
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'i' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'I' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '@' )
        {
            ByteString aToken;
            String aRespName( &aBuf[1], gsl_getSystemTextEncoding());
            SimpleConfig aConfig( aRespName );
            while ( (aToken = aConfig.GetNext()) != "")
            {
                char aBuf2[255];
                (void) strcpy( aBuf2, aToken.GetBuffer());
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'o' )
                {
                    strcpy(pOutputFileName, &aBuf2[3]);
                    //break;
                }
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'p' )
                {
                    strcpy(pSrsFileName, &aBuf2[3]);
                    String aName( pSrsFileName, gsl_getSystemTextEncoding());
                    DirEntry aDest( aName );
                    aSrsBaseName = aDest.GetBase();
                    //break;
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'i' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'I' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (( aBuf2[0] != '-' ) && ( aBuf2[0] != '@' ))
                {
                    pDep->AddSource( &aBuf2[0] );
                    aRespArg += " ";
                    aRespArg += &aBuf2[0];
                    bSource = TRUE;
                }
            }
        }
    }

    while( 1 )
    {
        c = simple_getopt( argv,
        "_abcdefghi:jklmnopqrstuvwxyzABCDEFGHI:JKLMNOPQRSTUVWXYZ1234567890/-+=.\\()\"");
        if ( c == -1 )
            break;

        switch( c )
        {
            case 0:
                break;
            case 'a' :
#ifdef DEBUG_VERBOSE
                printf("option a\n");
#endif
                break;

            case 'l' :
#ifdef DEBUG_VERBOSE
                printf("option l with Value %s\n", optarg );
#endif
                pDep->AddSource( optarg );
                break;

            case 'h' :
            case 'H' :
            case '?' :
                printf("RscDep 1.0 (c)2000 StarOffice\n");
                break;

            default:
#ifdef DEBUG_VERBOSE
                printf("Unknown getopt error\n");
#endif
                ;
        }
    }

    DirEntry aEntry(".");
    aEntry.ToAbs();
    String aCwd = aEntry.GetName();
/*  USHORT nPos;
#ifndef UNX
    while ( (nPos = aCwd.Search('\\') != STRING_NOTFOUND  ))
#else
    while ( (nPos = aCwd.Search('/') != STRING_NOTFOUND  ))
#endif
    {
        String attt = aCwd.Copy( 0, nPos );
        aCwd.Erase( 0, nPos );
    } */
    SvFileStream aOutStream;
    String aOutputFileName( pOutputFileName, gsl_getSystemTextEncoding());
    DirEntry aOutEntry( aOutputFileName );
    String aOutPath = aOutEntry.GetPath().GetFull();

    String aFileName( aOutPath );
    aFileName += aDelim;
    aFileName += aCwd;
    aFileName += String(".", gsl_getSystemTextEncoding());
    aFileName += aSrsBaseName;
    aFileName += String(".dprr", gsl_getSystemTextEncoding());
    //fprintf( stderr, "OutFileName : %s \n",aFileName.GetStr());
    aOutStream.Open( aFileName, STREAM_WRITE );

    ByteString aString;
    if ( optind < argc )
    {
#ifdef DEBUG_VERBOSE
        printf("further arguments : ");
#endif
        aString = ByteString( pSrsFileName );
        aString += ByteString(" : " );

        while ( optind < argc )
        {
            if (!bSource )
            {
                aString += ByteString(" " );
                aString += ByteString( argv[optind]);
                pDep->AddSource( argv[optind++]);
            }
            else
            {
                optind++;
            }
        }
    }
    aString += aRespArg;
    pDep->Execute();
    ByteStringList *pLst = pDep->GetDepList();
    ULONG nCount = pLst->Count();
    if ( nCount == 0 )
    {
        aOutStream.WriteLine( aString );
    }
    else
    {
        aString += ByteString( "\\" );
        aOutStream.WriteLine( aString );
    }

    for ( ULONG j=0; j<nCount; j++ )
    {
        ByteString *pStr = pLst->GetObject(j);
#ifdef UNX
        pStr->SearchAndReplaceAll('\\', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
#ifdef WNT
        pStr->SearchAndReplaceAll('/', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
        if ( j != (nCount-1) )
            *pStr += ByteString( "\\" );
        aOutStream.WriteLine( *pStr );
    }
    delete pDep;
    aOutStream.Close();

    return 0;
}

/* my very simple minded implementation of getopt()
 * it's too sad that getopt() is not available everywhere
 * note: this is not a full POSIX conforming getopt()
 */
int simple_getopt(char *argv[], const char *optstring)
{
    char *arg = argv[optind];

    /* skip all response file arguments */
    if ( arg ) {
        while ( *arg == '@' )
            arg = argv[++optind];

        if ( arg[0] == '-' && arg[1] != '\0' ) {
            const char *popt;
            int c = arg[1];
            if ( (popt = strchr(optstring, c)) == NULL ) {
                optopt = c;
                if ( opterr )
                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
                return '?';
            }
            if ( *(++popt) == ':') {
                 if ( arg[2] != '\0' ) {
                     optarg = ++arg;
                 } else {
                     optarg = argv[++optind];
                 }
             } else {
                 optarg = NULL;
             }
             ++optind;
             return c;
        }
    }
    return -1;
}

<|endoftext|>


<commit_before>#ifndef _MSP_PERIPH_HPP
#define _MSP_PERIPH_HPP

#include <msp430.h>
#include "msp430/msp_sys.hpp"
#include "utilities/circfifo.hpp"

#define REG_16(x) *((volatile uint16_t*)x)
#define REG_8(x) *((volatile uint8_t*)x)

namespace McuPeripheral {

struct DisableAllInterrupts {
	void operator () (){
		__dint();
	}
};

struct EnableAllInterrupts {
	void operator () (){
		__eint();
	}
};

template<uint8_t _ienable, uint8_t  _iflag>
struct DisableInterrupt {
	void operator () (){
		REG_8(_ienable) &= ~_iflag;
	}
};

template<uint8_t _ienable, uint8_t  _iflag>
struct EnableInterrupt {
	void operator () (){
		REG_8(_ienable) |= _iflag;
	}
};

//Should be a base class to inherit from
struct FakeDisableInterrupt {
	void operator () (){
		//Do nothing
	}
};

struct FakeEnableInterrupt {
	void operator () (){
		//Do nothing
	}
};

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
class Interrupts {
public:
	static FifoBuffer<uint8_t, 8, McuPeripheral::DisableInterrupt<_ienable,_txen>, EnableInterrupt<_ienable,_txen> > mTxBuffer;
	static FifoBuffer<uint8_t, 8, McuPeripheral::DisableInterrupt<_ienable,_rxen>, EnableInterrupt<_ienable,_rxen> > mRxBuffer;

	static void init() { REG_8(_ienable) &= ~(_rxen | _txen); }
	static DisableInterrupt<_ienable,_txen> disableTxInterrupt;
	static DisableInterrupt<_ienable,_rxen> disableRxInterrupt;
	static EnableInterrupt<_ienable,_txen> enableTxInterrupt;
	static EnableInterrupt<_ienable,_rxen> enableRxInterrupt;
};

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
FifoBuffer<uint8_t, 8, McuPeripheral::DisableInterrupt<_ienable,_txen>, EnableInterrupt<_ienable,_txen> > Interrupts<_ienable,_txen,_rxen>::mTxBuffer;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
FifoBuffer<uint8_t, 8, McuPeripheral::DisableInterrupt<_ienable,_rxen>, EnableInterrupt<_ienable,_rxen> > Interrupts<_ienable,_txen,_rxen>::mRxBuffer;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
DisableInterrupt<_ienable,_txen> Interrupts<_ienable,_txen,_rxen>::disableTxInterrupt;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
DisableInterrupt<_ienable,_rxen> Interrupts<_ienable,_txen,_rxen>::disableRxInterrupt;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
EnableInterrupt<_ienable,_txen> Interrupts<_ienable,_txen,_rxen>::enableTxInterrupt;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
EnableInterrupt<_ienable,_rxen> Interrupts<_ienable,_txen,_rxen>::enableRxInterrupt;

class FakeInterupts {
public:
	static FakeFifoBuffer mTxBuffer;
	static FakeFifoBuffer mRxBuffer;
	static void init() { return; }

	static FakeDisableInterrupt disableTxInterrupt;
	static FakeDisableInterrupt disableRxInterrupt;
	static FakeEnableInterrupt enableTxInterrupt;
	static FakeEnableInterrupt enableRxInterrupt;
};

}

#endif //_MSP_PERIPH_HPP
<commit_msg>Comment updates<commit_after>#ifndef _MSP_PERIPH_HPP
#define _MSP_PERIPH_HPP

#include <msp430.h>
#include "msp430/msp_sys.hpp"
#include "utilities/circfifo.hpp"

#define REG_16(x) *((volatile uint16_t*)x)
#define REG_8(x) *((volatile uint8_t*)x)

namespace McuPeripheral {

/**@brief Wrapper to disable all interrupts
 */
struct DisableAllInterrupts {
	void operator () (){
		__dint();
	}
};

/**@brief Wrapper to enable all interrupts
 */
struct EnableAllInterrupts {
	void operator () (){
		__eint();
	}
};

/**@brief Wrapper to disable specifc interrupt or interrupts
 * tparam _ienable the interrupt register that the _iflag is cleared to disable interrupts
 * tparam _iflag the flag in the _ienable register to be cleared for disabling interrupt
 */
template<uint8_t _ienable, uint8_t  _iflag>
struct DisableInterrupt {
	void operator () (){
		REG_8(_ienable) &= ~_iflag;
	}
};

/**@brief Wrapper to enable specifc interrupt or interrupts
 * tparam _ienable the interrupt register that the _iflag is cleared to enable interrupts
 * tparam _iflag the flag in the _ienable register to be cleared for enabling interrupt
 */
template<uint8_t _ienable, uint8_t  _iflag>
struct EnableInterrupt {
	void operator () (){
		REG_8(_ienable) |= _iflag;
	}
};

/**@brief Empty class that can be used as a dummy when interrupts are not needed for disabling or enabling
 */
struct FakeInterrupt {
	void operator () (){
		//Do nothing
	}
};

/**@brief Templated class for specifing interrupts used in communications
 * tparam _ienable the interrupt register that the _iflag is set/cleared for interrupts
 * tparam _txen tx flag for enabling and disabling interrupts
 * tparam _rxen rx flag for enabling and disabling interrupts
 */
template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
class Interrupts {
public:
	static FifoBuffer<uint8_t, 8, McuPeripheral::DisableInterrupt<_ienable,_txen>, EnableInterrupt<_ienable,_txen> > mTxBuffer;
	static FifoBuffer<uint8_t, 8, McuPeripheral::DisableInterrupt<_ienable,_rxen>, EnableInterrupt<_ienable,_rxen> > mRxBuffer;

	static void init() { REG_8(_ienable) &= ~(_rxen | _txen); }
	static DisableInterrupt<_ienable,_txen> disableTxInterrupt;
	static DisableInterrupt<_ienable,_rxen> disableRxInterrupt;
	static EnableInterrupt<_ienable,_txen> enableTxInterrupt;
	static EnableInterrupt<_ienable,_rxen> enableRxInterrupt;
};

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
FifoBuffer<uint8_t, 8, McuPeripheral::DisableInterrupt<_ienable,_txen>, EnableInterrupt<_ienable,_txen> > Interrupts<_ienable,_txen,_rxen>::mTxBuffer;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
FifoBuffer<uint8_t, 8, McuPeripheral::DisableInterrupt<_ienable,_rxen>, EnableInterrupt<_ienable,_rxen> > Interrupts<_ienable,_txen,_rxen>::mRxBuffer;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
DisableInterrupt<_ienable,_txen> Interrupts<_ienable,_txen,_rxen>::disableTxInterrupt;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
DisableInterrupt<_ienable,_rxen> Interrupts<_ienable,_txen,_rxen>::disableRxInterrupt;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
EnableInterrupt<_ienable,_txen> Interrupts<_ienable,_txen,_rxen>::enableTxInterrupt;

template<uint8_t _ienable,uint8_t _txen, uint8_t _rxen>
EnableInterrupt<_ienable,_rxen> Interrupts<_ienable,_txen,_rxen>::enableRxInterrupt;

/**@brief dummy class for interrupts that are used when interrupts are not to be enabled.
 *        this is used for polling functionality of the communication.
 */
class FakeInterupts {
public:
	static FakeFifoBuffer mTxBuffer;
	static FakeFifoBuffer mRxBuffer;
	static void init() { return; }

	static FakeInterrupt disableTxInterrupt;
	static FakeInterrupt disableRxInterrupt;
	static FakeInterrupt enableTxInterrupt;
	static FakeInterrupt enableRxInterrupt;
};

}

#endif //_MSP_PERIPH_HPP
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------//
//!
//! \file   MonteCarlo_TetMeshTrackLengthFluxEstimator.cpp
//! \author Alex Robinson, Eli Moll
//! \brief  Tet mesh flux estimator class declaration.
//!
//---------------------------------------------------------------------------//

// Moab Includes
#include <moab/Core.hpp>

// FRENSIE Includes
#include "MonteCarlo_TetMeshTrackLengthFluxEstimator.hpp"
#include "Utility_TetrahedronHelpers.hpp"
#include "Utility_MOABException.hpp"
#include "Utility_ContractException.hpp"
#include "Utility_ExceptionTestMacros.hpp"

namespace MonteCarlo{

// Constructor
template<typename ContributionMultiplierPolicy>
TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::TetMeshTrackLengthFluxEstimator(
		                      const Estimator::idType id,
				              const double multiplier,
				              const std::string input_mesh_file_name,
		                      const std::string output_mesh_file_name )
  : StandardEntityEstimator<moab::EntityHandle>( id, multiplier ),
    d_moab_interface( new moab::Core ),
    d_tet_meshset,
    d_kd_tree( new moab::AdaptiveKDTree( d_moab_interface.getRawPtr() ) ),
    d_kd_tree_root(),
    d_obb_tree( new moab::OrientedBoxTreeTool( d_moab_interface.getRawPtr() )),
    d_obb_tree_root(),
    d_last_visited_tet(),
    d_last_visited_cell(),
    d_tet_barycentric_transform_matrices()
{
  // ------------------------ Load Meshset ------------------------------------

  // Create empty MOAB meshset
  moab::EntityHandle d_tet_meshset;
  moab::ErrorCode return_value = d_moab_interface->create_meshset(
					moab::MESHSET_SET, d_tet_meshset);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Populate MOAB meshset with data from input file
  return_value = d_moab_interface->load_file(
                            input_mesh_file_name.c_str(), &d_tet_meshset);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Range (domain) of all tetrahedral elements
  moab::Range all_tet_elements;

  // ---------------------- Reduce Meshset to 3D ------------------------------

  // Extract 3D elements from meshset
  return_value = d_moab_interface->get_entities_by_dimension(
                        d_tet_meshset, 3, all_tet_elements);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Clear the meshset
  return_value = d_moab_interface->clear_meshset(&d_tet_meshset, 1);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Reconstruct the meshset using only 3D entitites
  return_value = d_moab_interface->add_entities(
                                         d_tet_meshset, all_tet_elements);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  unsigned int number_of_tets = all_tet_elements.size();

  for( moab::Range::const_iterator tet = all_tet_elements.begin();
       tet != all_tet_elements.end();
       ++tet )
    {
      // Extract the vertex data for the given tet
      std::vector<moab::EntityHandle> vertex_handles;
      d_moab_interface->get_connectivity( tet, 1, vertex_handles );

      // Test that the vertex entity contains four points
      TEST_FOR_EXCEPTION( vertex_handles.size() != 4,
			  Utility::MOABException,
			  "Error: tet found with incorrect number of vertices "
			  "(" << vertex_handles.size() << " != 4)" );

      moab::CartVect vertices[4];

      for( unsigned j = 0; j < vertex_handles.size(); ++j )
      {
	d_moab_interface->get_coords( &vertex_handles[j],
				      1,
				      vertices[j].array() );
      }

      // Calculate Barycentric Matrix
      moab::Matrix3& barycentric_transform_matrix =
	  d_tet_barycentric_transform_matrices[tet];

      Utility::calculateBarycentricTransformMatrix(
						                        vertices[0],
						                        vertices[1],
						                        vertices[2],
						                        vertices[3],
                                                barycentric_transform_matrix );

      // Calculate tet volumes
      boost::unordered_map<moab::EntityHandle,double> entity_volumes;

      entity_volumes[*tet] = Utility::calculateTetrahedronVolume( vertices[0],
								  vertices[1],
								  vertices[2],
								  vertices[3]);

      // Assign the entity volumes
      this->assignEntities( entity_volumes );
   }

  // ---------------------------- KD Trees ------------------------------------

  int current_dimension;

  // Get dimension of the input set
  current_dimension =
    d_moab_interface->dimension_from_handle(all_tet_elements[0]);

  moab::Range surface_triangles;

  // Determine the edges from the input set
  return_value = d_moab_interface->get_adjacencies( all_tet_elements,
						    current_dimension - 1,
						    true,
						    surface_triangles,
						    moab::Interface::UNION );

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  all_tet_elements.merge( surface_triangles );

  const char settings[]="MESHSET_FLAGS=0x1;TAG_NAME=0";
  moab::FileOptions fileopts(settings);

  d_kd_tree->build_tree(all_tet_elements, &d_kd_tree_root, &fileopts);

  // Set up OBB Tree (how is this done?)
}

// Set the response functions
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::setResponseFunctions(
   const Teuchos::Array<Teuchos::RCP<ResponseFunction> >& response_functions )
{
  for( unsigned i = 0; i < response_functions.size(); ++i )
  {
    if( !response_functions[i]->isSpatiallyUniform() )
    {
      std::cerr << "Warning: tetrahedral mesh track length estimators can only "
		<< "be used with spatially uniform response functions. Results from "
		<< "tetrahdedral mesh track length estimator " << getId()
		<< "will not be correct." << std::endl;
    }
  }
  StandardEntityEstimator::setResponseFunctions( response_functions );
}

// Set the particle types that can contribute to the estimator
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::setParticleTypes( const Teuchos::Array<ParticleType>& particle_types )
{
  Estimator::setParticleTypes( particle_types );
}

// Add current history estimator contribution
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::updateFromParticleSubtrackEndingEvent(
			      const ParticleState& particle,
			      const Geometry::ModuleTraits::InternalCellHandle,
			      const double track_length )
{

}

// Export the estimator data
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::exportData(
                                           EstimatorHDF5FileHandler& hdf5_file,
					                       const bool process_data ) const
{
  // Export data in FRENSIE formatting for data manipulation
  StandardEntityEstimator::exportData();

  // Export data for visualization
  if( process_data )
  {
    moab::Range all_tet_elements;
    moab::ErrorCode return_value = d_moab_interface->get_entities_by_dimension(
                                       d_tet_meshset, 3, all_tet_elements);

    TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                        Utility::MOABException,
                        moab::ErrorCodeStr[return_value] );

    // Process moments
    for ( moab::Range::const_iterator tet = all_tet_elements.begin();
	  tet != all_tet_elements.end();
	  ++tet )
    {
      double tet_volume = this->getEntityNormConstant( *tet );

      const Estimator::TwoEstimatorMomentsArray& tet_bin_data =
	this->getEntityBinData( *tet );

      Teuchos::Array<moab::Tag> mean_tag( tet_bin_data.size() ),
	relative_error_tag( tet_bin_data.size() );

      std::string mean_tag_prefix = "mean_";
      std::string relative_error_tag_prefix = "relative_error_";

      for( unsigned i = 0; i < tet_bin_data.size(); ++i )
      {
	double mean, relative_error;

	this->processMoments( tet_bin_data[i],
			      tet_volume,
			      mean,
			      relative_error );

	std::string bin_name = this->getBinName( i );
	std::string mean_tag_name = mean_tag_prefix + bin_name;
	std::string relative_error_tag_name = relative_error_tag_prefix +
	  bin_name;

	moab::ErrorCode return_value =
	  d_moab_interface->tag_get_handle(
				       mean_tag_name.c_str(),
				       1,
				       moab::MB_TYPE_DOUBLE,
				       mean_tag[i],
				       moab::MB_TAG_DENSE|moab::MB_TAG_CREAT );

	TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

	return_value = d_moab_interface->tag_set_data( mean_tag[i],
						       *tet,
						       1,
						       mean );

	TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );
      }
    }
  }
}

// Print the estimator data
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::print(
						       std::ostream& os ) const
{
  StandardEntityEstimator::printImplementation( os );
}

// Assign bin boundaries to an estimator dimension
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::assignBinBoundaries(
	const Teuchos::RCP<EstimatorDimensionDiscretization>& bin_boundaries )
{
  // if( bin_boundaries->getDimension() != ENERGY_DIMENSION )
  // {
  //    std::cerr << "Warning: " << bin_boundaries->getDimensionName()
  // 	      << " bins cannot be set for standard cell estimators. The bins "
  // 	      << "requested for tetrahdedral mesh flux estimator " << this->getId()
  // 	      << " will be ignored."
  // 	      << std::endl;
  // }
  else
    StandardEntityEstimator<cellIdType>::assignBinBoundaries( bin_boundaries );
}

} // end MonteCarlo namespace

//---------------------------------------------------------------------------//
// end MonteCarlo_TetMeshTrackLengthFluxEstimator.hpp
//---------------------------------------------------------------------------//
<commit_msg>Implemented most of the track length mesh tally contribution work.<commit_after>//---------------------------------------------------------------------------//
//!
//! \file   MonteCarlo_TetMeshTrackLengthFluxEstimator.cpp
//! \author Alex Robinson, Eli Moll
//! \brief  Tet mesh flux estimator class declaration.
//!
//---------------------------------------------------------------------------//

// Moab Includes
#include <moab/Core.hpp>

// FRENSIE Includes
#include "MonteCarlo_TetMeshTrackLengthFluxEstimator.hpp"
#include "Utility_TetrahedronHelpers.hpp"
#include "Utility_MOABException.hpp"
#include "Utility_ContractException.hpp"
#include "Utility_ExceptionTestMacros.hpp"

// Used for intersection data storage and comparison
struct ray_data {
  double intersect;
  moab::EntityHandle triangle;
};

// Compare and sort intersection data
inline static bool compare(const ray_data &a, const ray_data &b)
{
    return a.intersect < b.intersect;
}

namespace MonteCarlo{

// Constructor
template<typename ContributionMultiplierPolicy>
TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::TetMeshTrackLengthFluxEstimator(
		                      const Estimator::idType id,
				              const double multiplier,
				              const std::string input_mesh_file_name,
		                      const std::string output_mesh_file_name )
  : StandardEntityEstimator<moab::EntityHandle>( id, multiplier ),
    d_moab_interface( new moab::Core ),
    d_tet_meshset,
    d_kd_tree( new moab::AdaptiveKDTree( d_moab_interface.getRawPtr() ) ),
    d_kd_tree_root(),
    d_obb_tree( new moab::OrientedBoxTreeTool( d_moab_interface.getRawPtr() )),
    d_obb_tree_root(),
    d_last_visited_tet(),
    d_last_visited_cell(),
    d_tet_barycentric_transform_matrices()
{
  // ------------------------ Load Meshset ------------------------------------

  // Create empty MOAB meshset
  moab::EntityHandle d_tet_meshset;
  moab::ErrorCode return_value = d_moab_interface->create_meshset(
					moab::MESHSET_SET, d_tet_meshset);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Populate MOAB meshset with data from input file
  return_value = d_moab_interface->load_file(
                            input_mesh_file_name.c_str(), &d_tet_meshset);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Range (domain) of all tetrahedral elements
  moab::Range all_tet_elements;

  // ---------------------- Reduce Meshset to 3D ------------------------------

  // Extract 3D elements from meshset
  return_value = d_moab_interface->get_entities_by_dimension(
                        d_tet_meshset, 3, all_tet_elements);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Clear the meshset
  return_value = d_moab_interface->clear_meshset(&d_tet_meshset, 1);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Reconstruct the meshset using only 3D entitites
  return_value = d_moab_interface->add_entities(
                                         d_tet_meshset, all_tet_elements);

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  unsigned int number_of_tets = all_tet_elements.size();

  for( moab::Range::const_iterator tet = all_tet_elements.begin();
       tet != all_tet_elements.end();
       ++tet )
    {
      // Extract the vertex data for the given tet
      std::vector<moab::EntityHandle> vertex_handles;
      d_moab_interface->get_connectivity( tet, 1, vertex_handles );

      // Test that the vertex entity contains four points
      TEST_FOR_EXCEPTION( vertex_handles.size() != 4,
			  Utility::MOABException,
			  "Error: tet found with incorrect number of vertices "
			  "(" << vertex_handles.size() << " != 4)" );

      moab::CartVect vertices[4];

      for( unsigned j = 0; j < vertex_handles.size(); ++j )
      {
	d_moab_interface->get_coords( &vertex_handles[j],
				      1,
				      vertices[j].array() );
      }

      // Calculate Barycentric Matrix
      moab::Matrix3& barycentric_transform_matrix =
	  d_tet_barycentric_transform_matrices[tet];

      Utility::calculateBarycentricTransformMatrix(
						                        vertices[0],
						                        vertices[1],
						                        vertices[2],
						                        vertices[3],
                                                barycentric_transform_matrix );

      // Calculate tet volumes
      boost::unordered_map<moab::EntityHandle,double> entity_volumes;

      entity_volumes[*tet] = Utility::calculateTetrahedronVolume( vertices[0],
								  vertices[1],
								  vertices[2],
								  vertices[3]);

      // Assign the entity volumes
      this->assignEntities( entity_volumes );
   }

  // ---------------------------- KD Trees ------------------------------------

  int current_dimension;

  // Get dimension of the input set
  current_dimension =
    d_moab_interface->dimension_from_handle(all_tet_elements[0]);

  moab::Range surface_triangles;

  // Determine the edges from the input set
  return_value = d_moab_interface->get_adjacencies( all_tet_elements,
						    current_dimension - 1,
						    true,
						    surface_triangles,
						    moab::Interface::UNION );

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  all_tet_elements.merge( surface_triangles );

  const char settings[]="MESHSET_FLAGS=0x1;TAG_NAME=0";
  moab::FileOptions fileopts(settings);

  d_kd_tree->build_tree(all_tet_elements, &d_kd_tree_root, &fileopts);

  // Set up OBB Tree (how is this done?)
}

// Set the response functions
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::setResponseFunctions(
   const Teuchos::Array<Teuchos::RCP<ResponseFunction> >& response_functions )
{
  for( unsigned i = 0; i < response_functions.size(); ++i )
  {
    if( !response_functions[i]->isSpatiallyUniform() )
    {
      std::cerr << "Warning: tetrahedral mesh track length estimators can only "
		<< "be used with spatially uniform response functions. Results from "
		<< "tetrahdedral mesh track length estimator " << getId()
		<< "will not be correct." << std::endl;
    }
  }
  StandardEntityEstimator::setResponseFunctions( response_functions );
}

// Set the particle types that can contribute to the estimator
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::setParticleTypes( const Teuchos::Array<ParticleType>& particle_types )
{
  Estimator::setParticleTypes( particle_types );
}

// Add current history estimator contribution
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::updateFromParticleSubtrackEndingEvent(
			      const ParticleState& particle,
			      const Geometry::ModuleTraits::InternalCellHandle,
			      const double track_length )
{
  std::vector<double> ray_tet_intersections;
  std::vector<moab::EntityHandle> tet_surface_triangles;

  // Get all intersections of the ray and the tets
  moab:ErrorCode return_value =
       d_kd_tree->ray_intersect_triangles( d_kd_tree_root,
                                           1e-6,
                                           particle.getDirection().array(),
                                           particle.getPosition().array(),
                                           tet_surface_triangles,
                                           ray_tet_intersections,
                                           0,
                                           track_length );

  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                      Utility::MOABException,
                      moab::ErrorCodeStr[return_value] );

  // Sort all intersections of the ray with the tets
  std::vector<ray_data> intersection_data;

  // Transfer the data to ray_data structures for sorting
  for( unsigned int i = 0; i < ray_tet_intersections.size(); i++ )
  {
    ray_data data;
    data.intersect = ray_tet_intersections[i];
    data.triangle  = tet_surface_triangles[i];
    intersection_data.push_back(data);
  }

  std::sort(intersection_data.begin(), intersection_data.end(), compare);

  // Transfer the data back to the previous data structures
  for( unsigned int i = 0; i < ray_tet_intersections.size(); i++ )
  {
    ray_tet_intersections[i] = intersection_data[i].intersect;
    tet_surface_triangles[i] = intersection_data[i].triangle;
  }

  // Account for the case where there are no intersections (entirely in tet)
  if( ray_tet_intersections.size() == 0 )
  {
    // FIGURE OUT HOW TO ADD TRACK LENGTH TO MESH TALLY
    // Map of tets and contributionss
    // Map here consists of [d_last_visited_tet] -> [track_length]
  }
  else
  {
    moab::CartVect hit_point;
    std::vector<moab::CartVect> array_of_hit_points;
    moab::CartVect tet_centroid;
    moab::EntityHandle tet;

    // Add the origin point of the ray to the array of points
    array_of_hit_points.push_back( particle.getPosition() );

    moab::EntityHandle next_tet_intersected = 0;

    for( unsigned int i = 0; i < ray_tet_intersections.size(); i++ )
    {
      hit_point = particle.getDirection()*ray_tet_intersections[i] +
                                                        particle.getPosition();
      array_of_hit_points.push_back(hit_point);
      tet_centroid = ( (array_of_hit_points[i+1]+array_of_hit_points[i])/2.0 );

      tet = POINT_IN_WHICH_TET ? Do we want to do this???

      if( tet > 0 )
      {
        if( i != 0)
          partial_track_length =
                        ray_tet_intersections[i] - ray_tet_intersections[i-1];
        else
          partial_track_length = ray_tet_intersections[i]j;
      }

      // FIGURE OUT HOW TO ADD TRACK LENGTH TO MESH TALLY
      // Map of tets and contributionss

    }

    // Get any left over track length
    if ( ray_tet_intersections[ray_tet_intersections.size() -1] < track_length )
    {
      partial_track_length = track_length -
                       ray_tet_intersections[ray_tet_intersections.size() - 1];

      tet = POINT IN WHICH TET ! Again need to talk about this!!!

      // FIGURE OUT HOW TO ADD TRACK LENGTH TO MESH TALLY
      // Map of tets and contributionss
    }

  }
}

// Export the estimator data
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::exportData(
                                           EstimatorHDF5FileHandler& hdf5_file,
					                       const bool process_data ) const
{
  // Export data in FRENSIE formatting for data manipulation
  StandardEntityEstimator::exportData();

  // Export data for visualization
  if( process_data )
  {
    moab::Range all_tet_elements;
    moab::ErrorCode return_value = d_moab_interface->get_entities_by_dimension(
                                       d_tet_meshset, 3, all_tet_elements);

    TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                        Utility::MOABException,
                        moab::ErrorCodeStr[return_value] );

    // Process moments
    for ( moab::Range::const_iterator tet = all_tet_elements.begin();
	  tet != all_tet_elements.end();
	  ++tet )
    {
      double tet_volume = this->getEntityNormConstant( *tet );

      const Estimator::TwoEstimatorMomentsArray& tet_bin_data =
	                                            this->getEntityBinData( *tet );

      Teuchos::Array<moab::Tag> mean_tag( tet_bin_data.size() + 1 ),
	  relative_error_tag( tet_bin_data.size() + 1 ),
	  vov_tag( tet_bin_data.size() + 1 ),
	  fom_tag( tet_bin_data.size() + 1 );

      std::string mean_tag_prefix = "mean_";
      std::string relative_error_tag_prefix = "relative_error_";
      std::string vov_tag_prefix = "vov_";
      std::string fom_tag_prefix = "fom_";

      for( unsigned i = 0; i < tet_bin_data.size(); ++i )
      {
    	double mean, relative_error;

    	this->processMoments( tet_bin_data[i],
            			      tet_volume,
            			      mean,
            			      relative_error );

    	std::string bin_name = this->getBinName( i );
    	std::string mean_tag_name = mean_tag_prefix + bin_name;
    	std::string relative_error_tag_name = relative_error_tag_prefix +
    	  bin_name;

	    // Assign mean tag data
	    moab::ErrorCode return_value = d_moab_interface->tag_get_handle(
		                               mean_tag_name.c_str(),
	                                   1,
	                                   moab::MB_TYPE_DOUBLE,
				                       mean_tag[i],
				                       moab::MB_TAG_DENSE|moab::MB_TAG_CREAT );

	    TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                            Utility::MOABException,
                            moab::ErrorCodeStr[return_value] );

	    return_value = d_moab_interface->tag_set_data( mean_tag[i],
		                        				       *tet,
		                        				       1,
						                               mean );

	    TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                            Utility::MOABException,
                            moab::ErrorCodeStr[return_value] );

        // Assign error tag data
	    moab::ErrorCode return_value = d_moab_interface->tag_get_handle(
		                               relative_error_tag_name.c_str(),
	                                   1,
	                                   moab::MB_TYPE_DOUBLE,
				                       relative_error_tag[i],
				                       moab::MB_TAG_DENSE|moab::MB_TAG_CREAT );

	    TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                            Utility::MOABException,
                            moab::ErrorCodeStr[return_value] );

	    return_value = d_moab_interface->tag_set_data( relative_error_tag[i],
		                        				       *tet,
		                        				       1,
						                               relative_error );

	    TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                            Utility::MOABException,
                            moab::ErrorCodeStr[return_value] );
      }

      // Assign total bin data for each entity
      std::string total_tag_prefix = "total_";
      std::string total_mean_tag_name = total_tag_prefix + "mean"
      std::string total_relative_error_tag_name = total_tag_prefix +
                                                          "relative_error"
      std::string total_vov_tag_name = total_tag_prefix + "vov"
      std::string total_fom_tag_name = total_tag_prefix + "fom"

      const Estimator::FourEstimatorMomentsArray& total_tet_bin_data =
	                                          this->getEntityTotalData( *tet );

      int end = tet_bin_data.size();
      double mean, relative_error, vov, fom;

      this->processMoments( total_tet_bin_data,
                            tet_volume,
                            mean,
                            relative_error,
                            vov,
                            fom);

      // Assign total mean tag data
	  moab::ErrorCode return_value = d_moab_interface->tag_get_handle(
		                             total_mean_tag_name.c_str(),
	                                 1,
	                                 moab::MB_TYPE_DOUBLE,
				                     mean_tag[end],
				                     moab::MB_TAG_DENSE|moab::MB_TAG_CREAT );

	  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                          Utility::MOABException,
                          moab::ErrorCodeStr[return_value] );

	  return_value = d_moab_interface->tag_set_data( mean_tag[end],
		                         				     *tet,
		                        				     1,
						                             mean );

	  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                          Utility::MOABException,
                          moab::ErrorCodeStr[return_value] );

      // Assign total relative error tag data
	  moab::ErrorCode return_value = d_moab_interface->tag_get_handle(
		                             total_relative_error_tag_name.c_str(),
	                                 1,
	                                 moab::MB_TYPE_DOUBLE,
				                     relative_error_tag[end],
				                     moab::MB_TAG_DENSE|moab::MB_TAG_CREAT );

	  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                          Utility::MOABException,
                          moab::ErrorCodeStr[return_value] );

	  return_value = d_moab_interface->tag_set_data( relative_error_tag[end],
		                         				     *tet,
		                        				     1,
						                             relative_error );

	  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                          Utility::MOABException,
                          moab::ErrorCodeStr[return_value] );

      // Assign total vov tag data
	  moab::ErrorCode return_value = d_moab_interface->tag_get_handle(
		                             total_vov_tag_name.c_str(),
	                                 1,
	                                 moab::MB_TYPE_DOUBLE,
				                     vov_tag[end],
				                     moab::MB_TAG_DENSE|moab::MB_TAG_CREAT );

	  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                          Utility::MOABException,
                          moab::ErrorCodeStr[return_value] );

	  return_value = d_moab_interface->tag_set_data( vov_tag[end],
		                         				     *tet,
		                        				     1,
						                             vov );

	  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                          Utility::MOABException,
                          moab::ErrorCodeStr[return_value] );

      // Assign total fom tag data
	  moab::ErrorCode return_value = d_moab_interface->tag_get_handle(
		                             total_fom_tag_name.c_str(),
	                                 1,
	                                 moab::MB_TYPE_DOUBLE,
				                     fom_tag[end],
				                     moab::MB_TAG_DENSE|moab::MB_TAG_CREAT );

	  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                          Utility::MOABException,
                          moab::ErrorCodeStr[return_value] );

	  return_value = d_moab_interface->tag_set_data( fom_tag[end],
		                         				     *tet,
		                        				     1,
						                             fom );

	  TEST_FOR_EXCEPTION( return_value != moab::MB_SUCCESS,
                          Utility::MOABException,
                          moab::ErrorCodeStr[return_value] );
    }
  }
}

// Print the estimator data
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::print(
						       std::ostream& os ) const
{
  StandardEntityEstimator::printImplementation( os );
}

// Assign bin boundaries to an estimator dimension
template<typename ContributionMultiplierPolicy>
void TetMeshTrackLengthFluxEstimator<ContributionMultiplierPolicy>::assignBinBoundaries(
	const Teuchos::RCP<EstimatorDimensionDiscretization>& bin_boundaries )
{
  if( bin_boundaries->getDimension() == COSINE_DIMENSION )
  {
    std::cerr << "Warning: " << bin_boundaries->getDimensionName()
    	      << " bins cannot be set for standard cell estimators. The bins "
     	      << "requested for tetrahdedral mesh flux estimator " << this->getId()
    	      << " will be ignored."
    	      << std::endl;
  }
  else if( bin_boundaries->getDimension() == TIME_DIMENSION )
  {
    std::cerr << "Warning: " << bin_boundaries->getDimensionName()
    	      << " bins cannot be set for standard cell estimators. The bins "
     	      << "requested for tetrahdedral mesh flux estimator " << this->getId()
    	      << " will be ignored."
    	      << std::endl;
  }
  else
    StandardEntityEstimator<cellIdType>::assignBinBoundaries( bin_boundaries );
}

} // end MonteCarlo namespace

//---------------------------------------------------------------------------//
// end MonteCarlo_TetMeshTrackLengthFluxEstimator.hpp
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>#include "shader_program.h"
#include "pathos/engine.h"
#include "pathos/render/render_device.h"
#include "pathos/util/log.h"
#include "pathos/util/resource_finder.h"

#include "badger/assertion/assertion.h"

#include <fstream>
#include <sstream>

#define DUMP_SHADER_SOURCE 0

namespace pathos {

	static struct InitRecompileShaders {
		InitRecompileShaders() {
			Engine::internal_registerGlobalRenderRoutine(InitRecompileShaders::recompileShaders, nullptr);
		}
		// Dirty but works anyway
		static void recompileShaders(OpenGLDevice* device) {
			gEngine->registerExec("recompile_shaders", [](const std::string& command) -> void {
				LOG(LogInfo, "Begin reloading shaders...");
				ShaderDB::get().forEach([](ShaderProgram* program) -> void {
					program->reload();
				});
				LOG(LogInfo, "End reloading shaders.");
			});
		}
	} internal_recompileShaders;

	ShaderProgram::ShaderProgram(const char* inDebugName, uint32 inProgramHash)
		: debugName(inDebugName)
		, programHash(inProgramHash)
		, glName(0xffffffff)
		, firstLoad(true)
		, internal_justInstantiated(true)
	{
		ShaderDB::get().registerProgram(inProgramHash, this);
	}

	ShaderProgram::~ShaderProgram()
	{
		CHECK(isValid());
		ShaderDB::get().unregisterProgram(programHash);
	}

	void ShaderProgram::addShaderStage(ShaderStage* shaderStage)
	{
		shaderStages.push_back(shaderStage);
	}

	void ShaderProgram::reload()
	{
		GLuint oldGLName = glName;
		bool oldValid = isValid();

		// Try to compile shader stages
		bool allCompiled = true;
		bool allNotChanged = true;
		for (ShaderStage* shaderStage : shaderStages) {
			ShaderStage::CompileResponse response = shaderStage->tryCompile();
			allCompiled = allCompiled && response != ShaderStage::CompileResponse::Failed;
			allNotChanged = allNotChanged && response == ShaderStage::CompileResponse::NotChanged;
		}
		if (allNotChanged) {
			LOG(LogDebug, "%s: All shader stages are not changed, won't recompile.", debugName);
			return;
		}
		if (!allCompiled) {
			LOG(LogDebug, "%s: Failed to compile some shader stages.", debugName);
			return;
		}

		// Finalize shader compilation
		for (ShaderStage* shaderStage : shaderStages) {
			shaderStage->finishCompile();
		}

		// Attach and link shader stages
		glName = glCreateProgram();
		glObjectLabel(GL_PROGRAM, glName, -1, debugName);
		for (ShaderStage* shaderStage : shaderStages) {
			glAttachShader(glName, shaderStage->getGLName());
		}
		glLinkProgram(glName);

		GLint isLinked = 0;
		glGetProgramiv(glName, GL_LINK_STATUS, &isLinked);

		if (isLinked == GL_FALSE) {
			// If linking failed, leave the old program as is.
			GLint maxLength = 0;
			glGetProgramiv(glName, GL_INFO_LOG_LENGTH, &maxLength);
			if (maxLength == 0) maxLength = 1024;
			std::vector<GLchar> infoLog(maxLength);
			glGetProgramInfoLog(glName, maxLength, &maxLength, infoLog.data());

			LOG(LogError, "program link error(code=%d): %s", glGetError(), infoLog.data());

			glDeleteProgram(glName);
			glName = oldGLName;
		} else {
			// If linked, replace old program with new one.
			if (oldValid) {
				glDeleteProgram(oldGLName);
			}
			if (!firstLoad) {
				LOG(LogDebug, "%s: Recompiled the shader program.", debugName);
			}
		}
	}

	void ShaderProgram::checkFirstLoad()
	{
		if (firstLoad) {
			reload();
			firstLoad = false;
		}
	}

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

	ShaderStage::ShaderStage(GLenum inShaderType, const char* inDebugName)
		: shaderType(inShaderType)
		, debugName(inDebugName)
		, glName(0)
		, pendingGLName(0)
		, filepath(nullptr)
	{
		CHECK( inShaderType == GL_VERTEX_SHADER
			|| inShaderType == GL_GEOMETRY_SHADER
			|| inShaderType == GL_TESS_CONTROL_SHADER
			|| inShaderType == GL_TESS_EVALUATION_SHADER
			|| inShaderType == GL_FRAGMENT_SHADER
			|| inShaderType == GL_COMPUTE_SHADER);
		CHECK(inDebugName != nullptr);
	}

	ShaderStage::~ShaderStage()
	{
		if (glName != 0) {
			glDeleteShader(glName);
		}
	}

	bool ShaderStage::loadSource()
	{
		CHECK(filepath != nullptr);

		std::string fullFilepath = ResourceFinder::get().find(filepath);

		if (fullFilepath.size() == 0) {
			LOG(LogError, "[%s]: Couldn't find file: %s", __FUNCTION__, filepath);
			return false;
		}

		std::ifstream fileStream(fullFilepath);
		if (fileStream.is_open() == false) {
			LOG(LogError, "[%s]: Couldn't open file: %s", __FUNCTION__, filepath);
			return false;
		}

		std::ostringstream codeStream;
		codeStream << fileStream.rdbuf();
		std::string fullCode = std::move(codeStream.str());

		size_t version_start = fullCode.find("#version");
		if (version_start == std::string::npos) {
			LOG(LogError, "[%s]: GLSL source file should contain '#version' statement", __FUNCTION__);
			return false;
		}

		size_t version_end = fullCode.find_first_of('\n', version_start);

		// Add defines
		if (defines.size() > 0) {
			codeStream.clear();
			codeStream.str("");
			// Put #version back
			codeStream << fullCode.substr(version_start, version_end - version_start + 1);
			for (const std::string& def : defines) {
				codeStream << "#define " << def << '\n';
			}
			codeStream << fullCode.substr(version_end + 1);
			fullCode = std::move(codeStream.str());
		}

		sourceCode.clear();

		size_t find_offset = 0u;
		while (true) {
			// #todo-shader: Need to skip '#include' in comments
			size_t include_start = fullCode.find("#include", find_offset);
			if (include_start == std::string::npos) {
				break;
			}

			size_t include_end = fullCode.find_first_of('\n', include_start);
			sourceCode.emplace_back(fullCode.substr(0, include_start));
			std::string include_line = fullCode.substr(include_start, include_end - include_start);

			size_t quote_start = include_line.find('"');
			size_t quote_end = include_line.find('"', quote_start + 1);
			CHECK(quote_start != std::string::npos && quote_end != std::string::npos);

			// #todo-shader: Support recursive include?
			std::string include_file = include_line.substr(quote_start + 1, quote_end - quote_start - 1);
			std::string include_filepath = ResourceFinder::get().find(include_file);
			std::ifstream subfile(include_filepath);
			if (!subfile.is_open()) {
				LOG(LogError, "Couldn't open a #include file: %s", include_filepath.c_str());
				return false;
			}
			std::ostringstream substream;
			substream << subfile.rdbuf();
			sourceCode.emplace_back(substream.str());

			fullCode = fullCode.substr(include_end + 1);
		}

		sourceCode.emplace_back(fullCode);

		return true;
	}

	ShaderStage::CompileResponse ShaderStage::tryCompile()
	{
		std::vector<std::string> sourceCodeBackup = sourceCode;
		loadSource();

		bool sourceChanged = false;
		if (sourceCode.size() == sourceCodeBackup.size()) {
			for (uint32 i = 0; i < sourceCode.size(); ++i) {
				if (sourceCode[i] != sourceCodeBackup[i]) {
					sourceChanged = true;
					break;
				}
			}
		} else {
			sourceChanged = true;
		}
		if (sourceChanged == false) {
			LOG(LogDebug, "%s: Source code is same.", debugName);
			return ShaderStage::CompileResponse::NotChanged;
		}

		if (pendingGLName != 0) {
			glDeleteShader(pendingGLName);
		}

		// #todo-shader-rework: Output shader code to intermediate/shader_dump
#if DUMP_SHADER_SOURCE
		//
#endif

		std::vector<const char*> sourceList;
		for (const auto& s : sourceCode) {
			sourceList.push_back(s.c_str());
		}

		pendingGLName = glCreateShader(shaderType);
		glShaderSource(pendingGLName, (GLsizei)sourceList.size(), sourceList.data(), NULL);
		glCompileShader(pendingGLName);

		GLint success;
		glGetShaderiv(pendingGLName, GL_COMPILE_STATUS, &success);

		if (success == GL_FALSE) {
			GLint logSize;
			glGetShaderiv(pendingGLName, GL_INFO_LOG_LENGTH, &logSize);

			std::string errorLog;
			errorLog.resize(logSize);
			glGetShaderInfoLog(pendingGLName, logSize, NULL, &errorLog[0]);
			LOG(LogError, "Failed to compile shader (%s) : %s", debugName, errorLog.c_str());

			glDeleteShader(pendingGLName);
			pendingGLName = 0;

			return ShaderStage::CompileResponse::Failed;
		}

		return ShaderStage::CompileResponse::Compiled;
	}

	bool ShaderStage::finishCompile()
	{
		if (pendingGLName == 0) {
			return false;
		}

		if (glName != 0) {
			glDeleteShader(glName);
		}

		glName = pendingGLName;
		pendingGLName = 0;

		glObjectLabel(GL_SHADER, glName, -1, debugName);

		return true;
	}

}
<commit_msg>No log for same shaders when recompiling<commit_after>#include "shader_program.h"
#include "pathos/engine.h"
#include "pathos/render/render_device.h"
#include "pathos/util/log.h"
#include "pathos/util/resource_finder.h"

#include "badger/assertion/assertion.h"

#include <fstream>
#include <sstream>

#define DUMP_SHADER_SOURCE 0
#define IGNORE_SAME_SHADERS_ON_RECOMPILE 1

namespace pathos {

	static struct InitRecompileShaders {
		InitRecompileShaders() {
			Engine::internal_registerGlobalRenderRoutine(InitRecompileShaders::recompileShaders, nullptr);
		}
		// Dirty but works anyway
		static void recompileShaders(OpenGLDevice* device) {
			gEngine->registerExec("recompile_shaders", [](const std::string& command) -> void {
				LOG(LogInfo, "Begin reloading shaders...");
				ShaderDB::get().forEach([](ShaderProgram* program) -> void {
					program->reload();
				});
				LOG(LogInfo, "End reloading shaders.");
			});
		}
	} internal_recompileShaders;

	ShaderProgram::ShaderProgram(const char* inDebugName, uint32 inProgramHash)
		: debugName(inDebugName)
		, programHash(inProgramHash)
		, glName(0xffffffff)
		, firstLoad(true)
		, internal_justInstantiated(true)
	{
		ShaderDB::get().registerProgram(inProgramHash, this);
	}

	ShaderProgram::~ShaderProgram()
	{
		CHECK(isValid());
		ShaderDB::get().unregisterProgram(programHash);
	}

	void ShaderProgram::addShaderStage(ShaderStage* shaderStage)
	{
		shaderStages.push_back(shaderStage);
	}

	void ShaderProgram::reload()
	{
		GLuint oldGLName = glName;
		bool oldValid = isValid();

		// Try to compile shader stages
		bool allCompiled = true;
		bool allNotChanged = true;
		for (ShaderStage* shaderStage : shaderStages) {
			ShaderStage::CompileResponse response = shaderStage->tryCompile();
			allCompiled = allCompiled && response != ShaderStage::CompileResponse::Failed;
			allNotChanged = allNotChanged && response == ShaderStage::CompileResponse::NotChanged;
		}
		if (allNotChanged) {
#if IGNORE_SAME_SHADERS_ON_RECOMPILE == 0
			LOG(LogDebug, "%s: All shader stages are not changed, won't recompile.", debugName);
#endif
			return;
		}
		if (!allCompiled) {
			LOG(LogDebug, "%s: Failed to compile some shader stages.", debugName);
			return;
		}

		// Finalize shader compilation
		for (ShaderStage* shaderStage : shaderStages) {
			shaderStage->finishCompile();
		}

		// Attach and link shader stages
		glName = glCreateProgram();
		glObjectLabel(GL_PROGRAM, glName, -1, debugName);
		for (ShaderStage* shaderStage : shaderStages) {
			glAttachShader(glName, shaderStage->getGLName());
		}
		glLinkProgram(glName);

		GLint isLinked = 0;
		glGetProgramiv(glName, GL_LINK_STATUS, &isLinked);

		if (isLinked == GL_FALSE) {
			// If linking failed, leave the old program as is.
			GLint maxLength = 0;
			glGetProgramiv(glName, GL_INFO_LOG_LENGTH, &maxLength);
			if (maxLength == 0) maxLength = 1024;
			std::vector<GLchar> infoLog(maxLength);
			glGetProgramInfoLog(glName, maxLength, &maxLength, infoLog.data());

			LOG(LogError, "program link error(code=%d): %s", glGetError(), infoLog.data());

			glDeleteProgram(glName);
			glName = oldGLName;
		} else {
			// If linked, replace old program with new one.
			if (oldValid) {
				glDeleteProgram(oldGLName);
			}
			if (!firstLoad) {
				LOG(LogDebug, "%s: Recompiled the shader program.", debugName);
			}
		}
	}

	void ShaderProgram::checkFirstLoad()
	{
		if (firstLoad) {
			reload();
			firstLoad = false;
		}
	}

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

	ShaderStage::ShaderStage(GLenum inShaderType, const char* inDebugName)
		: shaderType(inShaderType)
		, debugName(inDebugName)
		, glName(0)
		, pendingGLName(0)
		, filepath(nullptr)
	{
		CHECK( inShaderType == GL_VERTEX_SHADER
			|| inShaderType == GL_GEOMETRY_SHADER
			|| inShaderType == GL_TESS_CONTROL_SHADER
			|| inShaderType == GL_TESS_EVALUATION_SHADER
			|| inShaderType == GL_FRAGMENT_SHADER
			|| inShaderType == GL_COMPUTE_SHADER);
		CHECK(inDebugName != nullptr);
	}

	ShaderStage::~ShaderStage()
	{
		if (glName != 0) {
			glDeleteShader(glName);
		}
	}

	bool ShaderStage::loadSource()
	{
		CHECK(filepath != nullptr);

		std::string fullFilepath = ResourceFinder::get().find(filepath);

		if (fullFilepath.size() == 0) {
			LOG(LogError, "[%s]: Couldn't find file: %s", __FUNCTION__, filepath);
			return false;
		}

		std::ifstream fileStream(fullFilepath);
		if (fileStream.is_open() == false) {
			LOG(LogError, "[%s]: Couldn't open file: %s", __FUNCTION__, filepath);
			return false;
		}

		std::ostringstream codeStream;
		codeStream << fileStream.rdbuf();
		std::string fullCode = std::move(codeStream.str());

		size_t version_start = fullCode.find("#version");
		if (version_start == std::string::npos) {
			LOG(LogError, "[%s]: GLSL source file should contain '#version' statement", __FUNCTION__);
			return false;
		}

		size_t version_end = fullCode.find_first_of('\n', version_start);

		// Add defines
		if (defines.size() > 0) {
			codeStream.clear();
			codeStream.str("");
			// Put #version back
			codeStream << fullCode.substr(version_start, version_end - version_start + 1);
			for (const std::string& def : defines) {
				codeStream << "#define " << def << '\n';
			}
			codeStream << fullCode.substr(version_end + 1);
			fullCode = std::move(codeStream.str());
		}

		sourceCode.clear();

		size_t find_offset = 0u;
		while (true) {
			// #todo-shader: Need to skip '#include' in comments
			size_t include_start = fullCode.find("#include", find_offset);
			if (include_start == std::string::npos) {
				break;
			}

			size_t include_end = fullCode.find_first_of('\n', include_start);
			sourceCode.emplace_back(fullCode.substr(0, include_start));
			std::string include_line = fullCode.substr(include_start, include_end - include_start);

			size_t quote_start = include_line.find('"');
			size_t quote_end = include_line.find('"', quote_start + 1);
			CHECK(quote_start != std::string::npos && quote_end != std::string::npos);

			// #todo-shader: Support recursive include?
			std::string include_file = include_line.substr(quote_start + 1, quote_end - quote_start - 1);
			std::string include_filepath = ResourceFinder::get().find(include_file);
			std::ifstream subfile(include_filepath);
			if (!subfile.is_open()) {
				LOG(LogError, "Couldn't open a #include file: %s", include_filepath.c_str());
				return false;
			}
			std::ostringstream substream;
			substream << subfile.rdbuf();
			sourceCode.emplace_back(substream.str());

			fullCode = fullCode.substr(include_end + 1);
		}

		sourceCode.emplace_back(fullCode);

		return true;
	}

	ShaderStage::CompileResponse ShaderStage::tryCompile()
	{
		std::vector<std::string> sourceCodeBackup = sourceCode;
		loadSource();

		bool sourceChanged = false;
		if (sourceCode.size() == sourceCodeBackup.size()) {
			for (uint32 i = 0; i < sourceCode.size(); ++i) {
				if (sourceCode[i] != sourceCodeBackup[i]) {
					sourceChanged = true;
					break;
				}
			}
		} else {
			sourceChanged = true;
		}
		if (sourceChanged == false) {
#if IGNORE_SAME_SHADERS_ON_RECOMPILE == 0
			LOG(LogDebug, "%s: Source code is same.", debugName);
#endif
			return ShaderStage::CompileResponse::NotChanged;
		}

		if (pendingGLName != 0) {
			glDeleteShader(pendingGLName);
		}

		// #todo-shader-rework: Output shader code to intermediate/shader_dump
#if DUMP_SHADER_SOURCE
		//
#endif

		std::vector<const char*> sourceList;
		for (const auto& s : sourceCode) {
			sourceList.push_back(s.c_str());
		}

		pendingGLName = glCreateShader(shaderType);
		glShaderSource(pendingGLName, (GLsizei)sourceList.size(), sourceList.data(), NULL);
		glCompileShader(pendingGLName);

		GLint success;
		glGetShaderiv(pendingGLName, GL_COMPILE_STATUS, &success);

		if (success == GL_FALSE) {
			GLint logSize;
			glGetShaderiv(pendingGLName, GL_INFO_LOG_LENGTH, &logSize);

			std::string errorLog;
			errorLog.resize(logSize);
			glGetShaderInfoLog(pendingGLName, logSize, NULL, &errorLog[0]);
			LOG(LogError, "Failed to compile shader (%s) : %s", debugName, errorLog.c_str());

			glDeleteShader(pendingGLName);
			pendingGLName = 0;

			return ShaderStage::CompileResponse::Failed;
		}

		return ShaderStage::CompileResponse::Compiled;
	}

	bool ShaderStage::finishCompile()
	{
		if (pendingGLName == 0) {
			return false;
		}

		if (glName != 0) {
			glDeleteShader(glName);
		}

		glName = pendingGLName;
		pendingGLName = 0;

		glObjectLabel(GL_SHADER, glName, -1, debugName);

		return true;
	}

}
<|endoftext|>


<commit_before>#ifndef _PNMC_MC_STATISTICS_SERIALIZE_HH_
#define _PNMC_MC_STATISTICS_SERIALIZE_HH_

#include <cereal/archives/json.hpp>
#include <cereal/types/deque.hpp>

#include "conf/configuration.hh"
#include "mc/statistics.hh"

namespace pnmc { namespace mc {

/*------------------------------------------------------------------------------------------------*/

template<class Archive>
void
save(Archive& archive, const statistics& s)
{
  archive( cereal::make_nvp("interrupted", s.interrupted)
         , cereal::make_nvp("states", s.nb_states)
         , cereal::make_nvp("states as string", std::to_string(s.nb_states))
         , cereal::make_nvp("relation time", s.relation_duration.count())
         , cereal::make_nvp("rewrite time", s.rewrite_duration.count())
         , cereal::make_nvp("state space time", s.state_space_duration.count())
         , cereal::make_nvp("sdd samples", s.sdd_ut_size)
         );
  if (s.conf.order_ordering_force)
  {
    archive(cereal::make_nvp("FORCE time", s.force_duration.count()));
  }
  if (s.conf.compute_dead_states)
  {
    archive( cereal::make_nvp("dead states relation time", s.dead_states_relation_duration.count())
           , cereal::make_nvp("dead states rewrite time", s.dead_states_rewrite_duration.count())
           , cereal::make_nvp("dead states time", s.dead_states_duration.count())
           );
  }
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace pnmc::mc

#endif // _PNMC_MC_STATISTICS_SERIALIZE_HH_
<commit_msg>Add the time limit to serialized statistics.<commit_after>#ifndef _PNMC_MC_STATISTICS_SERIALIZE_HH_
#define _PNMC_MC_STATISTICS_SERIALIZE_HH_

#include <cereal/archives/json.hpp>
#include <cereal/types/deque.hpp>

#include "conf/configuration.hh"
#include "mc/statistics.hh"

namespace pnmc { namespace mc {

/*------------------------------------------------------------------------------------------------*/

template<class Archive>
void
save(Archive& archive, const statistics& s)
{
  archive( cereal::make_nvp("interrupted", s.interrupted)
         , cereal::make_nvp("time limit", s.conf.max_time.count())
         , cereal::make_nvp("states", s.nb_states)
         , cereal::make_nvp("states as string", std::to_string(s.nb_states))
         , cereal::make_nvp("relation time", s.relation_duration.count())
         , cereal::make_nvp("rewrite time", s.rewrite_duration.count())
         , cereal::make_nvp("state space time", s.state_space_duration.count())
         , cereal::make_nvp("sdd samples", s.sdd_ut_size)
         );
  if (s.conf.order_ordering_force)
  {
    archive(cereal::make_nvp("FORCE time", s.force_duration.count()));
  }
  if (s.conf.compute_dead_states)
  {
    archive( cereal::make_nvp("dead states relation time", s.dead_states_relation_duration.count())
           , cereal::make_nvp("dead states rewrite time", s.dead_states_rewrite_duration.count())
           , cereal::make_nvp("dead states time", s.dead_states_duration.count())
           );
  }
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace pnmc::mc

#endif // _PNMC_MC_STATISTICS_SERIALIZE_HH_
<|endoftext|>


<commit_before>/*
	Nazara Engine

	Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)

	Permission is hereby granted, free of charge, to any person obtaining a copy of
	this software and associated documentation files (the "Software"), to deal in
	the Software without restriction, including without limitation the rights to
	use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
	of the Software, and to permit persons to whom the Software is furnished to do
	so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in all
	copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
	SOFTWARE.
*/

#ifndef NAZARA_PREREQUISITES_HPP
#define NAZARA_PREREQUISITES_HPP

#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif

// Try to identify the compiler
#if defined(__BORLANDC__)
	#define NAZARA_COMPILER_BORDLAND
	#define NAZARA_DEPRECATED(txt)
	#define NAZARA_FUNCTION __FUNC__
#elif defined(__clang__)
	#define NAZARA_COMPILER_CLANG
	#define NAZARA_DEPRECATED(txt) __attribute__((__deprecated__(txt)))
	#define NAZARA_FUNCTION __PRETTY_FUNCTION__

	#ifdef __MINGW32__
		#define NAZARA_COMPILER_MINGW
		#ifdef __MINGW64_VERSION_MAJOR
			#define NAZARA_COMPILER_MINGW_W64
		#endif
	#endif
#elif defined(__GNUC__) || defined(__MINGW32__)
	#define NAZARA_COMPILER_GCC
	#define NAZARA_DEPRECATED(txt) __attribute__((__deprecated__(txt)))
	#define NAZARA_FUNCTION __PRETTY_FUNCTION__

	#ifdef __MINGW32__
		#define NAZARA_COMPILER_MINGW
		#ifdef __MINGW64_VERSION_MAJOR
			#define NAZARA_COMPILER_MINGW_W64
		#endif
	#endif
#elif defined(__INTEL_COMPILER) || defined(__ICL)
	#define NAZARA_COMPILER_INTEL
	#define NAZARA_DEPRECATED(txt)
	#define NAZARA_FUNCTION __FUNCTION__
#elif defined(_MSC_VER)
	#define NAZARA_COMPILER_MSVC
	#define NAZARA_DEPRECATED(txt) __declspec(deprecated(txt))
	#define NAZARA_FUNCTION __FUNCSIG__

	#if _MSC_VER >= 1900
		#define NAZARA_COMPILER_SUPPORTS_CPP11
	#endif

	#pragma warning(disable: 4251)
#else
	#define NAZARA_COMPILER_UNKNOWN
	#define NAZARA_DEPRECATED(txt)
	#define NAZARA_FUNCTION __func__ // __func__ has been standardized in C++ 2011

	#pragma message This compiler is not fully supported
#endif

#if !defined(NAZARA_COMPILER_SUPPORTS_CPP11) && defined(__cplusplus) && __cplusplus >= 201103L
	#define NAZARA_COMPILER_SUPPORTS_CPP11
#endif

#ifndef NAZARA_COMPILER_SUPPORTS_CPP11
	#error Nazara requires a C++11 compliant compiler
#endif

// Nazara version macro
#define NAZARA_VERSION_MAJOR 0
#define NAZARA_VERSION_MINOR 4
#define NAZARA_VERSION_PATCH 0

#include <Nazara/Core/Config.hpp>

// Try to identify target platform via defines
#if defined(_WIN32)
	#define NAZARA_PLATFORM_DESKTOP
	#define NAZARA_PLATFORM_WINDOWS

	#define NAZARA_EXPORT __declspec(dllexport)
	#define NAZARA_IMPORT __declspec(dllimport)

	// Somes defines for windows.h include..
	#if defined(NAZARA_BUILD)
		#ifndef WIN32_LEAN_AND_MEAN
			#define WIN32_LEAN_AND_MEAN
		#endif

		#ifndef NOMINMAX
			#define NOMINMAX
		#endif

		#if NAZARA_CORE_WINDOWS_NT6
			#define NAZARA_WINNT 0x0600
		#else
			#define NAZARA_WINNT 0x0501
		#endif

		// Keep the actual define if existing and greater than our requirement
		#if defined(_WIN32_WINNT)
			#if _WIN32_WINNT < NAZARA_WINNT
				#undef _WIN32_WINNT
				#define _WIN32_WINNT NAZARA_WINNT
			#endif
		#else
			#define _WIN32_WINNT NAZARA_WINNT
		#endif
	#endif
#elif defined(__linux__) || defined(__unix__)
	#define NAZARA_PLATFORM_DESKTOP
	#define NAZARA_PLATFORM_LINUX
	#define NAZARA_PLATFORM_POSIX

	#define NAZARA_EXPORT __attribute__((visibility ("default")))
	#define NAZARA_IMPORT __attribute__((visibility ("default")))
#elif defined(__APPLE__) && !TARGET_OS_IPHONE
	#define NAZARA_PLATFORM_DESKTOP
	#define NAZARA_PLATFORM_MACOS
	#define NAZARA_PLATFORM_POSIX

	#define NAZARA_EXPORT __attribute__((visibility ("default")))
	#define NAZARA_IMPORT __attribute__((visibility ("default")))
#else
	#error This operating system is not fully supported by the Nazara Engine

	#define NAZARA_PLATFORM_UNKNOWN
#endif

// Detect 64 bits
#if !defined(NAZARA_PLATFORM_x64) && (defined(_WIN64) ||  defined(__amd64__) || defined(__x86_64__) || defined(__ia64__) || defined(__ia64) || \
	defined(_M_IA64) || defined(__itanium__) || defined(__MINGW64__) || defined(_M_AMD64) || defined (_M_X64))
	#define NAZARA_PLATFORM_x64
#endif

#ifdef NAZARA_UNITY_BUILD
	#define NAZARA_ANONYMOUS_NAMESPACE NAZARA_UNITY_ID
	#define NAZARA_USE_ANONYMOUS_NAMESPACE using namespace NAZARA_UNITY_ID;
	#define NAZARA_ANONYMOUS_NAMESPACE_PREFIX(a) NAZARA_UNITY_ID::a
#else
	#define NAZARA_ANONYMOUS_NAMESPACE
	#define NAZARA_USE_ANONYMOUS_NAMESPACE
	#define NAZARA_ANONYMOUS_NAMESPACE_PREFIX(a) a
#endif

// A bunch of useful macros
#define NazaraPrefix(a, prefix) prefix ## a
#define NazaraPrefixMacro(a, prefix) NazaraPrefix(a, prefix)
#define NazaraSuffix(a, suffix) a ## suffix
#define NazaraSuffixMacro(a, suffix) NazaraSuffix(a, suffix)
#define NazaraStringify(s) #s
#define NazaraStringifyMacro(s) NazaraStringify(s) // http://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
#define NazaraUnused(a) (void) a

#include <climits>
#include <cstdint>

static_assert(CHAR_BIT == 8, "CHAR_BIT is expected to be 8");

static_assert(sizeof(int8_t)  == 1, "int8_t is not of the correct size" );
static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(int32_t) == 4, "int32_t is not of the correct size");
static_assert(sizeof(int64_t) == 8, "int64_t is not of the correct size");

static_assert(sizeof(uint8_t)  == 1, "uint8_t is not of the correct size" );
static_assert(sizeof(uint16_t) == 2, "uint16_t is not of the correct size");
static_assert(sizeof(uint32_t) == 4, "uint32_t is not of the correct size");
static_assert(sizeof(uint64_t) == 8, "uint64_t is not of the correct size");

namespace Nz
{
	using Int8 = int8_t;
	using UInt8 = uint8_t;

	using Int16 = int16_t;
	using UInt16 = uint16_t;

	using Int32 = int32_t;
	using UInt32 = uint32_t;

	using Int64 = int64_t;
	using UInt64 = uint64_t;
}

#endif // NAZARA_PREREQUISITES_HPP
<commit_msg>Update Prerequisites.hpp<commit_after>/*
	Nazara Engine

	Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)

	Permission is hereby granted, free of charge, to any person obtaining a copy of
	this software and associated documentation files (the "Software"), to deal in
	the Software without restriction, including without limitation the rights to
	use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
	of the Software, and to permit persons to whom the Software is furnished to do
	so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in all
	copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
	SOFTWARE.
*/

#ifndef NAZARA_PREREQUISITES_HPP
#define NAZARA_PREREQUISITES_HPP

// Try to identify the compiler
#if defined(__BORLANDC__)
	#define NAZARA_COMPILER_BORDLAND
	#define NAZARA_DEPRECATED(txt)
	#define NAZARA_FUNCTION __FUNC__
#elif defined(__clang__)
	#define NAZARA_COMPILER_CLANG
	#define NAZARA_DEPRECATED(txt) __attribute__((__deprecated__(txt)))
	#define NAZARA_FUNCTION __PRETTY_FUNCTION__

	#ifdef __MINGW32__
		#define NAZARA_COMPILER_MINGW
		#ifdef __MINGW64_VERSION_MAJOR
			#define NAZARA_COMPILER_MINGW_W64
		#endif
	#endif
#elif defined(__GNUC__) || defined(__MINGW32__)
	#define NAZARA_COMPILER_GCC
	#define NAZARA_DEPRECATED(txt) __attribute__((__deprecated__(txt)))
	#define NAZARA_FUNCTION __PRETTY_FUNCTION__

	#ifdef __MINGW32__
		#define NAZARA_COMPILER_MINGW
		#ifdef __MINGW64_VERSION_MAJOR
			#define NAZARA_COMPILER_MINGW_W64
		#endif
	#endif
#elif defined(__INTEL_COMPILER) || defined(__ICL)
	#define NAZARA_COMPILER_INTEL
	#define NAZARA_DEPRECATED(txt)
	#define NAZARA_FUNCTION __FUNCTION__
#elif defined(_MSC_VER)
	#define NAZARA_COMPILER_MSVC
	#define NAZARA_DEPRECATED(txt) __declspec(deprecated(txt))
	#define NAZARA_FUNCTION __FUNCSIG__

	#if _MSC_VER >= 1900
		#define NAZARA_COMPILER_SUPPORTS_CPP11
	#endif

	#pragma warning(disable: 4251)
#else
	#define NAZARA_COMPILER_UNKNOWN
	#define NAZARA_DEPRECATED(txt)
	#define NAZARA_FUNCTION __func__ // __func__ has been standardized in C++ 2011

	#pragma message This compiler is not fully supported
#endif

#if !defined(NAZARA_COMPILER_SUPPORTS_CPP11) && defined(__cplusplus) && __cplusplus >= 201103L
	#define NAZARA_COMPILER_SUPPORTS_CPP11
#endif

#ifndef NAZARA_COMPILER_SUPPORTS_CPP11
	#error Nazara requires a C++11 compliant compiler
#endif

// Nazara version macro
#define NAZARA_VERSION_MAJOR 0
#define NAZARA_VERSION_MINOR 4
#define NAZARA_VERSION_PATCH 0

#include <Nazara/Core/Config.hpp>

// Try to identify target platform via defines
#if defined(_WIN32)
	#define NAZARA_PLATFORM_DESKTOP
	#define NAZARA_PLATFORM_WINDOWS

	#define NAZARA_EXPORT __declspec(dllexport)
	#define NAZARA_IMPORT __declspec(dllimport)

	// Somes defines for windows.h include..
	#if defined(NAZARA_BUILD)
		#ifndef WIN32_LEAN_AND_MEAN
			#define WIN32_LEAN_AND_MEAN
		#endif

		#ifndef NOMINMAX
			#define NOMINMAX
		#endif

		#if NAZARA_CORE_WINDOWS_NT6
			#define NAZARA_WINNT 0x0600
		#else
			#define NAZARA_WINNT 0x0501
		#endif

		// Keep the actual define if existing and greater than our requirement
		#if defined(_WIN32_WINNT)
			#if _WIN32_WINNT < NAZARA_WINNT
				#undef _WIN32_WINNT
				#define _WIN32_WINNT NAZARA_WINNT
			#endif
		#else
			#define _WIN32_WINNT NAZARA_WINNT
		#endif
	#endif
#elif defined(__linux__) || defined(__unix__)
	#define NAZARA_PLATFORM_DESKTOP
	#define NAZARA_PLATFORM_LINUX
	#define NAZARA_PLATFORM_POSIX

	#define NAZARA_EXPORT __attribute__((visibility ("default")))
	#define NAZARA_IMPORT __attribute__((visibility ("default")))
#elif defined(__APPLE__)
	#include <TargetConditionals.h>
	#if TARGET_OS_IPHONE
		#define NAZARA_PLATFORM_IOS
	#else
		#define NAZARA_PLATFORM_DESKTOP
		#define NAZARA_PLATFORM_MACOS
	#endif
	#define NAZARA_PLATFORM_POSIX

	#define NAZARA_EXPORT __attribute__((visibility ("default")))
	#define NAZARA_IMPORT __attribute__((visibility ("default")))
#else
	#error This operating system is not fully supported by the Nazara Engine

	#define NAZARA_PLATFORM_UNKNOWN
#endif

// Detect 64 bits
#if !defined(NAZARA_PLATFORM_x64) && (defined(_WIN64) ||  defined(__amd64__) || defined(__x86_64__) || defined(__ia64__) || defined(__ia64) || \
	defined(_M_IA64) || defined(__itanium__) || defined(__MINGW64__) || defined(_M_AMD64) || defined (_M_X64))
	#define NAZARA_PLATFORM_x64
#endif

#ifdef NAZARA_UNITY_BUILD
	#define NAZARA_ANONYMOUS_NAMESPACE NAZARA_UNITY_ID
	#define NAZARA_USE_ANONYMOUS_NAMESPACE using namespace NAZARA_UNITY_ID;
	#define NAZARA_ANONYMOUS_NAMESPACE_PREFIX(a) NAZARA_UNITY_ID::a
#else
	#define NAZARA_ANONYMOUS_NAMESPACE
	#define NAZARA_USE_ANONYMOUS_NAMESPACE
	#define NAZARA_ANONYMOUS_NAMESPACE_PREFIX(a) a
#endif

// A bunch of useful macros
#define NazaraPrefix(a, prefix) prefix ## a
#define NazaraPrefixMacro(a, prefix) NazaraPrefix(a, prefix)
#define NazaraSuffix(a, suffix) a ## suffix
#define NazaraSuffixMacro(a, suffix) NazaraSuffix(a, suffix)
#define NazaraStringify(s) #s
#define NazaraStringifyMacro(s) NazaraStringify(s) // http://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
#define NazaraUnused(a) (void) a

#include <climits>
#include <cstdint>

static_assert(CHAR_BIT == 8, "CHAR_BIT is expected to be 8");

static_assert(sizeof(int8_t)  == 1, "int8_t is not of the correct size" );
static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(int32_t) == 4, "int32_t is not of the correct size");
static_assert(sizeof(int64_t) == 8, "int64_t is not of the correct size");

static_assert(sizeof(uint8_t)  == 1, "uint8_t is not of the correct size" );
static_assert(sizeof(uint16_t) == 2, "uint16_t is not of the correct size");
static_assert(sizeof(uint32_t) == 4, "uint32_t is not of the correct size");
static_assert(sizeof(uint64_t) == 8, "uint64_t is not of the correct size");

namespace Nz
{
	using Int8 = int8_t;
	using UInt8 = uint8_t;

	using Int16 = int16_t;
	using UInt16 = uint16_t;

	using Int32 = int32_t;
	using UInt32 = uint32_t;

	using Int64 = int64_t;
	using UInt64 = uint64_t;
}

#endif // NAZARA_PREREQUISITES_HPP
<|endoftext|>


<commit_before>#ifndef Texture_HPP
#define Texture_HPP

#include <VBE/config.hpp>
#include <VBE/graphics/OpenGL.hpp>
#include <VBE/graphics/TextureFormat.hpp>
#include <VBE/utils/NonCopyable.hpp>

class Texture : public NonCopyable {
	public:
		enum Type {
			Type2D = 0,
			Type2DArray,
			Type3D,
			TypeCubemap,
			TypeCount
		};

		virtual ~Texture();

		GLuint getHandle() const;
		TextureFormat::Format getFormat() const;
		Type getType() const;

#ifndef VBE_GLES2
		void setComparison(GLenum func, GLenum mode = GL_COMPARE_REF_TO_TEXTURE);
#endif
		void setFilter(GLenum min, GLenum mag);
		void setWrap(GLenum wrap);
		static unsigned int getMaxSlots();

		friend void swap(Texture& a, Texture& b);
	protected:
		Texture(Type type, TextureFormat::Format format = TextureFormat::RGBA);

		static void bind(Type type, const Texture* tex, unsigned int slot);
		static GLenum typeToGL(Type t);
	private:
		GLuint handle = 0;
		TextureFormat::Format format = TextureFormat::RGB;
		Type type = Type2D;

		static std::vector<std::vector<GLuint>> current;
		static unsigned int currentUnit;
		static int maxSlots;
};

#endif // Texture_HPP
<commit_msg>Update Texture.hpp<commit_after>#ifndef Texture_HPP
#define Texture_HPP

#include <VBE/config.hpp>
#include <VBE/graphics/OpenGL.hpp>
#include <VBE/graphics/TextureFormat.hpp>
#include <VBE/utils/NonCopyable.hpp>

///
/// \brief Texture is the base class for all the OpenGL texture types.
///
class Texture : public NonCopyable {
	public:
		///
		/// \brief The Type enum represents the different OpenGL texture Types, used by the subclasses.
		///
		enum Type {
			Type2D = 0, //< GL_TEXTURE_2D
			Type2DArray, //< GL_TEXTURE_2D_ARRAY
			Type3D, //< GL_TEXTURE_3D
			TypeCubemap, //< GL_TEXTURE_CUBEMAP
			TypeCount
		};

		///
		/// \brief Destructor
		///
		virtual ~Texture();

		///
		/// \brief Returns the OpenGL handle of this texture
		///
		GLuint getHandle() const;

		///
		/// \brief Returns this texture's pixel format
		///
		TextureFormat::Format getFormat() const;

		///
		/// \brief Returns the texture type
		/// \see Texture::Type
		///
		Type getType() const;

#ifndef VBE_GLES2
		void setComparison(GLenum func, GLenum mode = GL_COMPARE_REF_TO_TEXTURE);
#endif
		void setFilter(GLenum min, GLenum mag);
		void setWrap(GLenum wrap);
		static unsigned int getMaxSlots();

		friend void swap(Texture& a, Texture& b);
	protected:
		Texture(Type type, TextureFormat::Format format = TextureFormat::RGBA);

		static void bind(Type type, const Texture* tex, unsigned int slot);
		static GLenum typeToGL(Type t);
	private:
		GLuint handle = 0;
		TextureFormat::Format format = TextureFormat::RGB;
		Type type = Type2D;

		static std::vector<std::vector<GLuint>> current;
		static unsigned int currentUnit;
		static int maxSlots;
};

///
/// \class Window Window.hpp <VBE/system/Window.hpp>
/// \ingroup System
///
/// This base class provides common functionality that is available for all textures, such as setting
/// the wrapping/filtering/comparing modes.
///

#endif // Texture_HPP
<|endoftext|>