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

#ifndef __FRAMEWORK_MACROS_REGISTRATION_HXX_
#define __FRAMEWORK_MACROS_REGISTRATION_HXX_

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_MACROS_DEBUG_HXX_
#include <macros/debug.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
#include <com/sun/star/registry/XRegistryKey.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_REGISTRY_INVALIDREGISTRYEXCEPTION_HPP_
#include <com/sun/star/registry/InvalidRegistryException.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//  namespace
//_________________________________________________________________________________________________________________

//namespace framework{

/*_________________________________________________________________________________________________________________

    macros for registration of services
    Please use follow public macros only!

    1)  COMPONENTINFO( CLASS )                      => use it as parameter for COMPONENT_WRITEINFO( INFOS )
    2)  IFFACTORY( CLASS )                          => use it as parameter for COMPONENT_GETFACTORY( IFFACTORIES )
    3)  COMPONENTGETIMPLEMENTATIONENVIRONMENT       => use it to define exported function component_getImplementationEnvironment()
    4)  COMPONENTWRITEINFO( INFOS )                 => use it to define exported function component_writeInfo()
    5)  COMPONENTGETFACTORY( IFFACTORIES )          => use it to define exported function component_getFactory()

_________________________________________________________________________________________________________________*/

//*****************************************************************************************************************
//  public
//  use it as parameter for COMPONENT_WRITEINFO( INFOS )
//*****************************************************************************************************************

#define COMPONENTINFO( CLASS )                                                                                \
    try                                                                                \
    {                                                                                \
        /* Set default result of follow operations !!! */                                                                               \
        bReturn = sal_False;                                                                                \
        /* Do the follow only, if given key is valid ! */                                                                               \
        if ( xKey.is() == sal_True )                                                                                \
        {                                                                                \
            LOG_REGISTRATION_WRITEINFO( "\t\t\txKey is valid ...\n" )                                                                   \
            /* Build new keyname    */                                                                                \
            sKeyName     =  DECLARE_ASCII( "/" );                                                                                \
            sKeyName    +=  CLASS::impl_getStaticImplementationName();                                                                  \
            sKeyName    +=  DECLARE_ASCII( "/UNO/SERVICES" );                                                                           \
            LOG_REGISTRATION_WRITEINFO( "\t\t\tcreate key \"" )                                                                         \
            LOG_REGISTRATION_WRITEINFO( U2B( sKeyName ) )                                                                               \
            LOG_REGISTRATION_WRITEINFO( "\" ...\n" )                                                                                \
            /* Create new key with new name. */                                                                                \
             xNewKey = xKey->createKey( sKeyName );                                                                                \
            /* If this new key valid ... */                                                                                \
            if ( xNewKey.is() == sal_True )                                                                                \
            {                                                                                \
                LOG_REGISTRATION_WRITEINFO( "\t\t\t\ttsuccessful ...\n" )                                                               \
                /* Get information about supported services. */                                                                         \
                seqServiceNames =   CLASS::impl_getStaticSupportedServiceNames()    ;                                                   \
                pArray          =   seqServiceNames.getArray()                      ;                                                   \
                nLength         =   seqServiceNames.getLength()                     ;                                                   \
                nCounter        =   0                                               ;                                                   \
                /* Then set this information on this key. */                                                                            \
                for ( nCounter = 0; nCounter < nLength; ++nCounter )                                                                    \
                {                                                                                \
                    LOG_REGISTRATION_WRITEINFO( "\t\t\t\twrite key \"" )                                                                \
                    LOG_REGISTRATION_WRITEINFO( U2B( pArray[nCounter] ) )                                                               \
                    LOG_REGISTRATION_WRITEINFO( "\" to registry ...\n" )                                                                \
                    xNewKey->createKey( pArray[nCounter] );                                                                             \
                }                                                                                \
                /* Result of this operations = OK. */                                                                                \
                bReturn = sal_True ;                                                                                \
            }                                                                                \
        }                                                                                \
    }                                                                                \
    catch( ::com::sun::star::registry::InvalidRegistryException& )                                                                      \
    {                                                                                \
        LOG_REGISTRATION_WRITEINFO( "\n\nERROR:\nInvalidRegistryException detected\n\n" )                                               \
        bReturn = sal_False ;                                                                                \
    }

//*****************************************************************************************************************
//  public
//  use it as parameter for COMPONENT_GETFACTORY( IFFACTORIES )
//*****************************************************************************************************************
#define IFFACTORY( CLASS )                                                                                \
    /* If searched name found ... */                                                                                \
    /* You can't add some statements before follow line ... Here can be an ELSE-statement! */                                           \
    if ( CLASS::impl_getStaticImplementationName().equals( ::rtl::OUString::createFromAscii( pImplementationName ) ) )                  \
    {                                                                                \
        LOG_REGISTRATION_GETFACTORY( "\t\tImplementationname found - try to create factory! ...\n" )                                    \
        /* ... then create right factory for this service.                                  */                                          \
        /* xFactory and xServiceManager are local variables of method which use this macro. */                                          \
        xFactory = CLASS::impl_createFactory( xServiceManager );                                                                        \
    }

//*****************************************************************************************************************
//  public
//  define helper to get information about service environment
//*****************************************************************************************************************
#define COMPONENTGETIMPLEMENTATIONENVIRONMENT                                                                                \
    extern "C" void SAL_CALL component_getImplementationEnvironment( const  sal_Char**          ppEnvironmentTypeName   ,               \
                                                                             uno_Environment**  ppEnvironment           )               \
    {                                                                                \
        *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;                                                                   \
    }

//*****************************************************************************************************************
//  public
//  define registration of service
//*****************************************************************************************************************
#define COMPONENTWRITEINFO( INFOS )                                                                                \
    extern "C" sal_Bool SAL_CALL component_writeInfo(   void*   pServiceManager ,                                                       \
                                                        void*   pRegistryKey    )                                                       \
    {                                                                                \
        LOG_REGISTRATION_WRITEINFO( "\t[start]\n" )                                                                                \
        /* Set default return value for this operation - if it failed. */                                                               \
        sal_Bool bReturn = sal_False ;                                                                                \
        if ( pRegistryKey != NULL )                                                                                \
        {                                                                                \
            LOG_REGISTRATION_WRITEINFO( "\t\tpRegistryKey is valid ...\n" )                                                             \
            /* Define variables for following helper macros! */                                                                         \
            /* bReturn will set automaticly.                 */                                                                         \
            ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey >    xKey            ;                           \
            ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey >    xNewKey         ;                           \
            ::com::sun::star::uno::Sequence<  ::rtl::OUString >                             seqServiceNames ;                           \
            const ::rtl::OUString*                                                          pArray          ;                           \
            sal_Int32                                                                       nLength         ;                           \
            sal_Int32                                                                       nCounter        ;                           \
            ::rtl::OUString                                                                 sKeyName        ;                           \
            xKey = reinterpret_cast< ::com::sun::star::registry::XRegistryKey* >( pRegistryKey );                                       \
            /* This parameter will expand to */                                                                                \
            /*   "COMPONENT_INFO(a)          */                                                                                \
            /*    ...                        */                                                                                \
            /*    COMPONENT_INFO(z)"         */                                                                                \
            INFOS                                                                                \
        }                                                                                \
        LOG_REGISTRATION_WRITEINFO( "\t[end]\n" )                                                                                \
        /* Return with result of this operation. */                                                                                \
        return bReturn ;                                                                                \
    }

//*****************************************************************************************************************
//  public
//  define method to instanciate new services
//*****************************************************************************************************************
#define COMPONENTGETFACTORY( IFFACTORIES )                                                                                \
    extern "C" void* SAL_CALL component_getFactory( const   sal_Char*   pImplementationName ,                                           \
                                                            void*       pServiceManager     ,                                           \
                                                            void*       pRegistryKey        )                                           \
    {                                                                                \
        LOG_REGISTRATION_GETFACTORY( "\t[start]\n" )                                                                                \
        /* Set default return value for this operation - if it failed. */                                                               \
        void* pReturn = NULL ;                                                                                \
        if  (                                                                                \
                ( pImplementationName   !=  NULL ) &&                                                                                \
                ( pServiceManager       !=  NULL )                                                                                \
            )                                                                                \
        {                                                                                \
            LOG_REGISTRATION_GETFACTORY( "\t\tpImplementationName and pServiceManager are valid ...\n" )                                \
            /* Define variables which are used in following macros. */                                                                  \
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory >   xFactory            ;                   \
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    xServiceManager     ;                   \
            xServiceManager = reinterpret_cast< ::com::sun::star::lang::XMultiServiceFactory* >( pServiceManager )  ;                   \
            /* These parameter will expand to      */                                                                                \
            /* "IF_NAME_CREATECOMPONENTFACTORY(a)  */                                                                                \
            /*  else                               */                                                                                \
            /*  ...                                */                                                                                \
            /*  else                               */                                                                                \
            /*  IF_NAME_CREATECOMPONENTFACTORY(z)" */                                                                                \
            IFFACTORIES                                                                                \
            /* Factory is valid, if service was found. */                                                                               \
            if ( xFactory.is() == sal_True )                                                                                \
            {                                                                                \
                LOG_REGISTRATION_GETFACTORY( "\t\t\txFactory valid - service was found ...\n" )                                         \
                xFactory->acquire();                                                                                \
                pReturn = xFactory.get();                                                                                \
            }                                                                                \
        }                                                                                \
        LOG_REGISTRATION_GETFACTORY( "\t[end]\n" )                                                                                \
        /* Return with result of this operation. */                                                                                \
        return pReturn ;                                                                                \
    }

//}     //  namespace framework

#endif  //  #ifndef __FRAMEWORK_MACROS_REGISTRATION_HXX_
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.242); FILE MERGED 2005/09/05 13:05:02 rt 1.2.242.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: registration.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 00:24:22 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef __FRAMEWORK_MACROS_REGISTRATION_HXX_
#define __FRAMEWORK_MACROS_REGISTRATION_HXX_

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_MACROS_DEBUG_HXX_
#include <macros/debug.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
#include <com/sun/star/registry/XRegistryKey.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_REGISTRY_INVALIDREGISTRYEXCEPTION_HPP_
#include <com/sun/star/registry/InvalidRegistryException.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//  namespace
//_________________________________________________________________________________________________________________

//namespace framework{

/*_________________________________________________________________________________________________________________

    macros for registration of services
    Please use follow public macros only!

    1)  COMPONENTINFO( CLASS )                      => use it as parameter for COMPONENT_WRITEINFO( INFOS )
    2)  IFFACTORY( CLASS )                          => use it as parameter for COMPONENT_GETFACTORY( IFFACTORIES )
    3)  COMPONENTGETIMPLEMENTATIONENVIRONMENT       => use it to define exported function component_getImplementationEnvironment()
    4)  COMPONENTWRITEINFO( INFOS )                 => use it to define exported function component_writeInfo()
    5)  COMPONENTGETFACTORY( IFFACTORIES )          => use it to define exported function component_getFactory()

_________________________________________________________________________________________________________________*/

//*****************************************************************************************************************
//  public
//  use it as parameter for COMPONENT_WRITEINFO( INFOS )
//*****************************************************************************************************************

#define COMPONENTINFO( CLASS )                                                                                \
    try                                                                                \
    {                                                                                \
        /* Set default result of follow operations !!! */                                                                               \
        bReturn = sal_False;                                                                                \
        /* Do the follow only, if given key is valid ! */                                                                               \
        if ( xKey.is() == sal_True )                                                                                \
        {                                                                                \
            LOG_REGISTRATION_WRITEINFO( "\t\t\txKey is valid ...\n" )                                                                   \
            /* Build new keyname    */                                                                                \
            sKeyName     =  DECLARE_ASCII( "/" );                                                                                \
            sKeyName    +=  CLASS::impl_getStaticImplementationName();                                                                  \
            sKeyName    +=  DECLARE_ASCII( "/UNO/SERVICES" );                                                                           \
            LOG_REGISTRATION_WRITEINFO( "\t\t\tcreate key \"" )                                                                         \
            LOG_REGISTRATION_WRITEINFO( U2B( sKeyName ) )                                                                               \
            LOG_REGISTRATION_WRITEINFO( "\" ...\n" )                                                                                \
            /* Create new key with new name. */                                                                                \
             xNewKey = xKey->createKey( sKeyName );                                                                                \
            /* If this new key valid ... */                                                                                \
            if ( xNewKey.is() == sal_True )                                                                                \
            {                                                                                \
                LOG_REGISTRATION_WRITEINFO( "\t\t\t\ttsuccessful ...\n" )                                                               \
                /* Get information about supported services. */                                                                         \
                seqServiceNames =   CLASS::impl_getStaticSupportedServiceNames()    ;                                                   \
                pArray          =   seqServiceNames.getArray()                      ;                                                   \
                nLength         =   seqServiceNames.getLength()                     ;                                                   \
                nCounter        =   0                                               ;                                                   \
                /* Then set this information on this key. */                                                                            \
                for ( nCounter = 0; nCounter < nLength; ++nCounter )                                                                    \
                {                                                                                \
                    LOG_REGISTRATION_WRITEINFO( "\t\t\t\twrite key \"" )                                                                \
                    LOG_REGISTRATION_WRITEINFO( U2B( pArray[nCounter] ) )                                                               \
                    LOG_REGISTRATION_WRITEINFO( "\" to registry ...\n" )                                                                \
                    xNewKey->createKey( pArray[nCounter] );                                                                             \
                }                                                                                \
                /* Result of this operations = OK. */                                                                                \
                bReturn = sal_True ;                                                                                \
            }                                                                                \
        }                                                                                \
    }                                                                                \
    catch( ::com::sun::star::registry::InvalidRegistryException& )                                                                      \
    {                                                                                \
        LOG_REGISTRATION_WRITEINFO( "\n\nERROR:\nInvalidRegistryException detected\n\n" )                                               \
        bReturn = sal_False ;                                                                                \
    }

//*****************************************************************************************************************
//  public
//  use it as parameter for COMPONENT_GETFACTORY( IFFACTORIES )
//*****************************************************************************************************************
#define IFFACTORY( CLASS )                                                                                \
    /* If searched name found ... */                                                                                \
    /* You can't add some statements before follow line ... Here can be an ELSE-statement! */                                           \
    if ( CLASS::impl_getStaticImplementationName().equals( ::rtl::OUString::createFromAscii( pImplementationName ) ) )                  \
    {                                                                                \
        LOG_REGISTRATION_GETFACTORY( "\t\tImplementationname found - try to create factory! ...\n" )                                    \
        /* ... then create right factory for this service.                                  */                                          \
        /* xFactory and xServiceManager are local variables of method which use this macro. */                                          \
        xFactory = CLASS::impl_createFactory( xServiceManager );                                                                        \
    }

//*****************************************************************************************************************
//  public
//  define helper to get information about service environment
//*****************************************************************************************************************
#define COMPONENTGETIMPLEMENTATIONENVIRONMENT                                                                                \
    extern "C" void SAL_CALL component_getImplementationEnvironment( const  sal_Char**          ppEnvironmentTypeName   ,               \
                                                                             uno_Environment**  ppEnvironment           )               \
    {                                                                                \
        *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;                                                                   \
    }

//*****************************************************************************************************************
//  public
//  define registration of service
//*****************************************************************************************************************
#define COMPONENTWRITEINFO( INFOS )                                                                                \
    extern "C" sal_Bool SAL_CALL component_writeInfo(   void*   pServiceManager ,                                                       \
                                                        void*   pRegistryKey    )                                                       \
    {                                                                                \
        LOG_REGISTRATION_WRITEINFO( "\t[start]\n" )                                                                                \
        /* Set default return value for this operation - if it failed. */                                                               \
        sal_Bool bReturn = sal_False ;                                                                                \
        if ( pRegistryKey != NULL )                                                                                \
        {                                                                                \
            LOG_REGISTRATION_WRITEINFO( "\t\tpRegistryKey is valid ...\n" )                                                             \
            /* Define variables for following helper macros! */                                                                         \
            /* bReturn will set automaticly.                 */                                                                         \
            ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey >    xKey            ;                           \
            ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey >    xNewKey         ;                           \
            ::com::sun::star::uno::Sequence<  ::rtl::OUString >                             seqServiceNames ;                           \
            const ::rtl::OUString*                                                          pArray          ;                           \
            sal_Int32                                                                       nLength         ;                           \
            sal_Int32                                                                       nCounter        ;                           \
            ::rtl::OUString                                                                 sKeyName        ;                           \
            xKey = reinterpret_cast< ::com::sun::star::registry::XRegistryKey* >( pRegistryKey );                                       \
            /* This parameter will expand to */                                                                                \
            /*   "COMPONENT_INFO(a)          */                                                                                \
            /*    ...                        */                                                                                \
            /*    COMPONENT_INFO(z)"         */                                                                                \
            INFOS                                                                                \
        }                                                                                \
        LOG_REGISTRATION_WRITEINFO( "\t[end]\n" )                                                                                \
        /* Return with result of this operation. */                                                                                \
        return bReturn ;                                                                                \
    }

//*****************************************************************************************************************
//  public
//  define method to instanciate new services
//*****************************************************************************************************************
#define COMPONENTGETFACTORY( IFFACTORIES )                                                                                \
    extern "C" void* SAL_CALL component_getFactory( const   sal_Char*   pImplementationName ,                                           \
                                                            void*       pServiceManager     ,                                           \
                                                            void*       pRegistryKey        )                                           \
    {                                                                                \
        LOG_REGISTRATION_GETFACTORY( "\t[start]\n" )                                                                                \
        /* Set default return value for this operation - if it failed. */                                                               \
        void* pReturn = NULL ;                                                                                \
        if  (                                                                                \
                ( pImplementationName   !=  NULL ) &&                                                                                \
                ( pServiceManager       !=  NULL )                                                                                \
            )                                                                                \
        {                                                                                \
            LOG_REGISTRATION_GETFACTORY( "\t\tpImplementationName and pServiceManager are valid ...\n" )                                \
            /* Define variables which are used in following macros. */                                                                  \
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory >   xFactory            ;                   \
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    xServiceManager     ;                   \
            xServiceManager = reinterpret_cast< ::com::sun::star::lang::XMultiServiceFactory* >( pServiceManager )  ;                   \
            /* These parameter will expand to      */                                                                                \
            /* "IF_NAME_CREATECOMPONENTFACTORY(a)  */                                                                                \
            /*  else                               */                                                                                \
            /*  ...                                */                                                                                \
            /*  else                               */                                                                                \
            /*  IF_NAME_CREATECOMPONENTFACTORY(z)" */                                                                                \
            IFFACTORIES                                                                                \
            /* Factory is valid, if service was found. */                                                                               \
            if ( xFactory.is() == sal_True )                                                                                \
            {                                                                                \
                LOG_REGISTRATION_GETFACTORY( "\t\t\txFactory valid - service was found ...\n" )                                         \
                xFactory->acquire();                                                                                \
                pReturn = xFactory.get();                                                                                \
            }                                                                                \
        }                                                                                \
        LOG_REGISTRATION_GETFACTORY( "\t[end]\n" )                                                                                \
        /* Return with result of this operation. */                                                                                \
        return pReturn ;                                                                                \
    }

//}     //  namespace framework

#endif  //  #ifndef __FRAMEWORK_MACROS_REGISTRATION_HXX_
<|endoftext|>


<commit_before>// $Id$

#include "TreeInput.h"
#include "StaticData.h"
#include "Util.h"
#include "XmlOption.h"
#include "FactorCollection.h"

using namespace std;

namespace Moses
{

/**
 * Process a sentence with xml annotation
 * Xml tags may specifiy additional/replacing translation options
 * and reordering constraints
 *
 * \param line in: sentence, out: sentence without the xml
 * \param res vector with translation options specified by xml
 * \param reorderingConstraint reordering constraint zones specified by xml
 * \param walls reordering constraint walls specified by xml
 */
bool TreeInput::ProcessAndStripXMLTags(string &line, std::vector<XMLParseOutput> &sourceLabels, std::vector<XmlOption*> &xmlOptions)
{
  //parse XML markup in translation line

  // no xml tag? we're done.
  if (line.find_first_of('<') == string::npos) {
    return true;
  }

  // break up input into a vector of xml tags and text
  // example: (this), (), (is a), (), (test .)
  vector<string> xmlTokens = TokenizeXml(line);

  // we need to store opened tags, until they are closed
  // tags are stored as tripled (tagname, startpos, contents)
  typedef pair< string, pair< size_t, string > > OpenedTag;
  vector< OpenedTag > tagStack; // stack that contains active opened tags

  string cleanLine; // return string (text without xml)
  size_t wordPos = 0; // position in sentence (in terms of number of words)

  // keep this handy for later
  const vector<FactorType> &outputFactorOrder = StaticData::Instance().GetOutputFactorOrder();
  // const string &factorDelimiter = StaticData::Instance().GetFactorDelimiter();

  // loop through the tokens
  for (size_t xmlTokenPos = 0 ; xmlTokenPos < xmlTokens.size() ; xmlTokenPos++) {
    // not a xml tag, but regular text (may contain many words)
    if(!isXmlTag(xmlTokens[xmlTokenPos])) {
      // add a space at boundary, if necessary
      if (cleanLine.size()>0 &&
          cleanLine[cleanLine.size() - 1] != ' ' &&
          xmlTokens[xmlTokenPos][0] != ' ') {
        cleanLine += " ";
      }
      cleanLine += xmlTokens[xmlTokenPos]; // add to output
      wordPos = Tokenize(cleanLine).size(); // count all the words
    }

    // process xml tag
    else {
      // *** get essential information about tag ***

      // strip extra boundary spaces and "<" and ">"
      string tag =  Trim(TrimXml(xmlTokens[xmlTokenPos]));
      VERBOSE(3,"XML TAG IS: " << tag << std::endl);

      if (tag.size() == 0) {
        TRACE_ERR("ERROR: empty tag name: " << line << endl);
        return false;
      }

      // check if unary (e.g., "<wall/>")
      bool isUnary = ( tag[tag.size() - 1] == '/' );

      // check if opening tag (e.g. "", not "")g
      bool isClosed = ( tag[0] == '/' );
      bool isOpen = !isClosed;

      if (isClosed && isUnary) {
        TRACE_ERR("ERROR: can't have both closed and unary tag <" << tag << ">: " << line << endl);
        return false;
      }

      if (isClosed)
        tag = tag.substr(1); // remove "/" at the beginning
      if (isUnary)
        tag = tag.substr(0,tag.size()-1); // remove "/" at the end

      // find the tag name and contents
      string::size_type endOfName = tag.find_first_of(' ');
      string tagName = tag;
      string tagContent = "";
      if (endOfName != string::npos) {
        tagName = tag.substr(0,endOfName);
        tagContent = tag.substr(endOfName+1);
      }

      // *** process new tag ***

      if (isOpen || isUnary) {
        // put the tag on the tag stack
        OpenedTag openedTag = make_pair( tagName, make_pair( wordPos, tagContent ) );
        tagStack.push_back( openedTag );
        VERBOSE(3,"XML TAG " << tagName << " (" << tagContent << ") added to stack, now size " << tagStack.size() << endl);
      }

      // *** process completed tag ***

      if (isClosed || isUnary) {
        // pop last opened tag from stack;
        if (tagStack.size() == 0) {
          TRACE_ERR("ERROR: tag " << tagName << " closed, but not opened" << ":" << line << endl);
          return false;
        }
        OpenedTag openedTag = tagStack.back();
        tagStack.pop_back();

        // tag names have to match
        if (openedTag.first != tagName) {
          TRACE_ERR("ERROR: tag " << openedTag.first << " closed by tag " << tagName << ": " << line << endl );
          return false;
        }

        // assemble remaining information about tag
        size_t startPos = openedTag.second.first;
        string tagContent = openedTag.second.second;
        size_t endPos = wordPos;

        // span attribute overwrites position
        string span = ParseXmlTagAttribute(tagContent,"span");
        if (! span.empty()) {
          vector<string> ij = Tokenize(span, "-");
          if (ij.size() != 1 && ij.size() != 2) {
            TRACE_ERR("ERROR: span attribute must be of the form \"i-j\" or \"i\": " << line << endl);
            return false;
          }
          startPos = atoi(ij[0].c_str());
          if (ij.size() == 1) endPos = startPos + 1;
          else endPos = atoi(ij[1].c_str()) + 1;
        }

        VERBOSE(3,"XML TAG " << tagName << " (" << tagContent << ") spanning " << startPos << " to " << (endPos-1) << " complete, commence processing" << endl);

        if (startPos >= endPos) {
          TRACE_ERR("ERROR: tag " << tagName << " must span at least one word: " << line << endl);
          return false;
        }

        // may be either a input span label ("label"), or a specified output translation "translation"
        string label = ParseXmlTagAttribute(tagContent,"label");
        string translation = ParseXmlTagAttribute(tagContent,"translation");

        // specified label
        if (translation.length() == 0 && label.length() > 0) {
          WordsRange range(startPos,endPos-1); // really?
          XMLParseOutput item(label, range);
          sourceLabels.push_back(item);
        }

        // specified translations -> vector of phrases, separated by "||"
        if (translation.length() > 0 && StaticData::Instance().GetXmlInputType() != XmlIgnore) {
          vector<string> altTexts = TokenizeMultiCharSeparator(translation, "||");
          vector<string> altLabel = TokenizeMultiCharSeparator(label, "||");
          vector<string> altProbs = TokenizeMultiCharSeparator(ParseXmlTagAttribute(tagContent,"prob"), "||");
          //TRACE_ERR("number of translations: " << altTexts.size() << endl);
          for (size_t i=0; i<altTexts.size(); ++i) {
            // set target phrase
            TargetPhrase targetPhrase;
            // targetPhrase.CreateFromString(Output, outputFactorOrder,altTexts[i],factorDelimiter, NULL);
            targetPhrase.CreateFromString(Output, outputFactorOrder,altTexts[i], NULL);

            // set constituent label
            string targetLHSstr;
            if (altLabel.size() > i && altLabel[i].size() > 0) {
              targetLHSstr = altLabel[i];
            } else {
              const UnknownLHSList &lhsList = StaticData::Instance().GetUnknownLHS();
              UnknownLHSList::const_iterator iterLHS = lhsList.begin();
              targetLHSstr = iterLHS->first;
            }
            Word *targetLHS = new Word(true);
            targetLHS->CreateFromString(Output, outputFactorOrder, targetLHSstr, true);
            UTIL_THROW_IF2(targetLHS->GetFactor(0) == NULL,
            		"Null factor left-hand-side");
            targetPhrase.SetTargetLHS(targetLHS);

            // not tested
            Phrase sourcePhrase = this->GetSubString(WordsRange(startPos,endPos-1));

            // get probability
            float probValue = 1;
            if (altProbs.size() > i && altProbs[i].size() > 0) {
              probValue = Scan<float>(altProbs[i]);
            }
            // convert from prob to log-prob
            float scoreValue = FloorScore(TransformScore(probValue));
            targetPhrase.SetXMLScore(scoreValue);
            targetPhrase.Evaluate(sourcePhrase);

            // set span and create XmlOption
            WordsRange range(startPos+1,endPos);
            XmlOption *option = new XmlOption(range,targetPhrase);
            assert(option);
            xmlOptions.push_back(option);

            VERBOSE(2,"xml translation = [" << range << "] " << targetLHSstr << " -> " << altTexts[i] << " prob: " << probValue << endl);
          }
          altTexts.clear();
          altProbs.clear();
        }
      }
    }
  }
  // we are done. check if there are tags that are still open
  if (tagStack.size() > 0) {
    TRACE_ERR("ERROR: some opened tags were never closed: " << line << endl);
    return false;
  }

  // return de-xml'ed sentence in line
  line = cleanLine;
  return true;
}

//! populate this InputType with data from in stream
int TreeInput::Read(std::istream& in,const std::vector<FactorType>& factorOrder)
{
  const StaticData &staticData = StaticData::Instance();

  string line;
  if (getline(in, line, '\n').eof())
    return 0;
  // remove extra spaces
  //line = Trim(line);

  std::vector<XMLParseOutput> sourceLabels;
  ProcessAndStripXMLTags(line, sourceLabels, m_xmlOptions);

  // do words 1st - hack
  stringstream strme;
  strme << line << endl;

  Sentence::Read(strme, factorOrder);

  // size input chart
  size_t sourceSize = GetSize();
  m_sourceChart.resize(sourceSize);

  for (size_t pos = 0; pos < sourceSize; ++pos) {
    m_sourceChart[pos].resize(sourceSize - pos);
  }

  // do source labels
  vector<XMLParseOutput>::const_iterator iterLabel;
  for (iterLabel = sourceLabels.begin(); iterLabel != sourceLabels.end(); ++iterLabel) {
    const XMLParseOutput &labelItem = *iterLabel;
    const WordsRange &range = labelItem.m_range;
    const string &label = labelItem.m_label;
    AddChartLabel(range.GetStartPos() + 1, range.GetEndPos() + 1, label, factorOrder);
  }

  // default label
  for (size_t startPos = 0; startPos < sourceSize; ++startPos) {
    for (size_t endPos = startPos; endPos < sourceSize; ++endPos) {
      NonTerminalSet &list = GetLabelSet(startPos, endPos);
      if (list.size() == 0 || !staticData.GetDefaultNonTermOnlyForEmptyRange()) {
        AddChartLabel(startPos, endPos, staticData.GetInputDefaultNonTerminal(), factorOrder);
      }
    }
  }

  return 1;
}

//! Output debugging info to stream out
void TreeInput::Print(std::ostream &out) const
{
  out << *this << "\n";
}

//! create trans options specific to this InputType
TranslationOptionCollection* TreeInput::CreateTranslationOptionCollection() const
{

  return NULL;
}

void TreeInput::AddChartLabel(size_t startPos, size_t endPos, const Word &label
                              , const std::vector<FactorType>& /* factorOrder */)
{
  UTIL_THROW_IF2(!label.IsNonTerminal(),
		  "Label must be a non-terminal");

  SourceLabelOverlap overlapType = StaticData::Instance().GetSourceLabelOverlap();
  NonTerminalSet &list = GetLabelSet(startPos, endPos);
  switch (overlapType) {
  case SourceLabelOverlapAdd:
    list.insert(label);
    break;
  case SourceLabelOverlapReplace:
    if (list.size() > 0) // replace existing label
      list.clear();
    list.insert(label);
    break;
  case SourceLabelOverlapDiscard:
    if (list.size() == 0)
      list.insert(label);
    break;
  }
}

void TreeInput::AddChartLabel(size_t startPos, size_t endPos, const string &label
                              , const std::vector<FactorType>& factorOrder)
{
  Word word(true);
  const Factor *factor = FactorCollection::Instance().AddFactor(Input, factorOrder[0], label, true); // TODO - no factors
  word.SetFactor(0, factor);

  AddChartLabel(startPos, endPos, word, factorOrder);
}

std::ostream& operator<<(std::ostream &out, const TreeInput &input)
{
  out<< static_cast<Phrase const&>(input) << " ||| ";

  size_t size = input.GetSize();
  for (size_t startPos = 0; startPos < size; ++startPos) {
    for (size_t endPos = startPos; endPos < size; ++endPos) {
      const NonTerminalSet &labelSet = input.GetLabelSet(startPos, endPos);
      NonTerminalSet::const_iterator iter;
      for (iter = labelSet.begin(); iter != labelSet.end(); ++iter) {
        const Word &word = *iter;
        UTIL_THROW_IF2(!word.IsNonTerminal(),
      		  "Word must be a non-terminal");
        out << "[" << startPos <<"," << endPos << "]="
            << word << "(" << word.IsNonTerminal() << ") ";
      }
    }
  }

  return out;
}

} // namespace

<commit_msg>warning for empty tags, instead of error<commit_after>// $Id$

#include "TreeInput.h"
#include "StaticData.h"
#include "Util.h"
#include "XmlOption.h"
#include "FactorCollection.h"

using namespace std;

namespace Moses
{

/**
 * Process a sentence with xml annotation
 * Xml tags may specifiy additional/replacing translation options
 * and reordering constraints
 *
 * \param line in: sentence, out: sentence without the xml
 * \param res vector with translation options specified by xml
 * \param reorderingConstraint reordering constraint zones specified by xml
 * \param walls reordering constraint walls specified by xml
 */
bool TreeInput::ProcessAndStripXMLTags(string &line, std::vector<XMLParseOutput> &sourceLabels, std::vector<XmlOption*> &xmlOptions)
{
  //parse XML markup in translation line

  // no xml tag? we're done.
  if (line.find_first_of('<') == string::npos) {
    return true;
  }

  // break up input into a vector of xml tags and text
  // example: (this), (), (is a), (), (test .)
  vector<string> xmlTokens = TokenizeXml(line);

  // we need to store opened tags, until they are closed
  // tags are stored as tripled (tagname, startpos, contents)
  typedef pair< string, pair< size_t, string > > OpenedTag;
  vector< OpenedTag > tagStack; // stack that contains active opened tags

  string cleanLine; // return string (text without xml)
  size_t wordPos = 0; // position in sentence (in terms of number of words)

  // keep this handy for later
  const vector<FactorType> &outputFactorOrder = StaticData::Instance().GetOutputFactorOrder();
  // const string &factorDelimiter = StaticData::Instance().GetFactorDelimiter();

  // loop through the tokens
  for (size_t xmlTokenPos = 0 ; xmlTokenPos < xmlTokens.size() ; xmlTokenPos++) {
    // not a xml tag, but regular text (may contain many words)
    if(!isXmlTag(xmlTokens[xmlTokenPos])) {
      // add a space at boundary, if necessary
      if (cleanLine.size()>0 &&
          cleanLine[cleanLine.size() - 1] != ' ' &&
          xmlTokens[xmlTokenPos][0] != ' ') {
        cleanLine += " ";
      }
      cleanLine += xmlTokens[xmlTokenPos]; // add to output
      wordPos = Tokenize(cleanLine).size(); // count all the words
    }

    // process xml tag
    else {
      // *** get essential information about tag ***

      // strip extra boundary spaces and "<" and ">"
      string tag =  Trim(TrimXml(xmlTokens[xmlTokenPos]));
      VERBOSE(3,"XML TAG IS: " << tag << std::endl);

      if (tag.size() == 0) {
        TRACE_ERR("ERROR: empty tag name: " << line << endl);
        return false;
      }

      // check if unary (e.g., "<wall/>")
      bool isUnary = ( tag[tag.size() - 1] == '/' );

      // check if opening tag (e.g. "", not "")g
      bool isClosed = ( tag[0] == '/' );
      bool isOpen = !isClosed;

      if (isClosed && isUnary) {
        TRACE_ERR("ERROR: can't have both closed and unary tag <" << tag << ">: " << line << endl);
        return false;
      }

      if (isClosed)
        tag = tag.substr(1); // remove "/" at the beginning
      if (isUnary)
        tag = tag.substr(0,tag.size()-1); // remove "/" at the end

      // find the tag name and contents
      string::size_type endOfName = tag.find_first_of(' ');
      string tagName = tag;
      string tagContent = "";
      if (endOfName != string::npos) {
        tagName = tag.substr(0,endOfName);
        tagContent = tag.substr(endOfName+1);
      }

      // *** process new tag ***

      if (isOpen || isUnary) {
        // put the tag on the tag stack
        OpenedTag openedTag = make_pair( tagName, make_pair( wordPos, tagContent ) );
        tagStack.push_back( openedTag );
        VERBOSE(3,"XML TAG " << tagName << " (" << tagContent << ") added to stack, now size " << tagStack.size() << endl);
      }

      // *** process completed tag ***

      if (isClosed || isUnary) {
        // pop last opened tag from stack;
        if (tagStack.size() == 0) {
          TRACE_ERR("ERROR: tag " << tagName << " closed, but not opened" << ":" << line << endl);
          return false;
        }
        OpenedTag openedTag = tagStack.back();
        tagStack.pop_back();

        // tag names have to match
        if (openedTag.first != tagName) {
          TRACE_ERR("ERROR: tag " << openedTag.first << " closed by tag " << tagName << ": " << line << endl );
          return false;
        }

        // assemble remaining information about tag
        size_t startPos = openedTag.second.first;
        string tagContent = openedTag.second.second;
        size_t endPos = wordPos;

        // span attribute overwrites position
        string span = ParseXmlTagAttribute(tagContent,"span");
        if (! span.empty()) {
          vector<string> ij = Tokenize(span, "-");
          if (ij.size() != 1 && ij.size() != 2) {
            TRACE_ERR("ERROR: span attribute must be of the form \"i-j\" or \"i\": " << line << endl);
            return false;
          }
          startPos = atoi(ij[0].c_str());
          if (ij.size() == 1) endPos = startPos + 1;
          else endPos = atoi(ij[1].c_str()) + 1;
        }

        VERBOSE(3,"XML TAG " << tagName << " (" << tagContent << ") spanning " << startPos << " to " << (endPos-1) << " complete, commence processing" << endl);

        if (startPos == endPos) {
          TRACE_ERR("WARNING: tag " << tagName << " span is empty. Ignoring: " << line << endl);
          continue;
        }
        else if (startPos > endPos) {
          TRACE_ERR("ERROR: tag " << tagName << " startPos > endPos: " << line << endl);
          return false;
        }

        // may be either a input span label ("label"), or a specified output translation "translation"
        string label = ParseXmlTagAttribute(tagContent,"label");
        string translation = ParseXmlTagAttribute(tagContent,"translation");

        // specified label
        if (translation.length() == 0 && label.length() > 0) {
          WordsRange range(startPos,endPos-1); // really?
          XMLParseOutput item(label, range);
          sourceLabels.push_back(item);
        }

        // specified translations -> vector of phrases, separated by "||"
        if (translation.length() > 0 && StaticData::Instance().GetXmlInputType() != XmlIgnore) {
          vector<string> altTexts = TokenizeMultiCharSeparator(translation, "||");
          vector<string> altLabel = TokenizeMultiCharSeparator(label, "||");
          vector<string> altProbs = TokenizeMultiCharSeparator(ParseXmlTagAttribute(tagContent,"prob"), "||");
          //TRACE_ERR("number of translations: " << altTexts.size() << endl);
          for (size_t i=0; i<altTexts.size(); ++i) {
            // set target phrase
            TargetPhrase targetPhrase;
            // targetPhrase.CreateFromString(Output, outputFactorOrder,altTexts[i],factorDelimiter, NULL);
            targetPhrase.CreateFromString(Output, outputFactorOrder,altTexts[i], NULL);

            // set constituent label
            string targetLHSstr;
            if (altLabel.size() > i && altLabel[i].size() > 0) {
              targetLHSstr = altLabel[i];
            } else {
              const UnknownLHSList &lhsList = StaticData::Instance().GetUnknownLHS();
              UnknownLHSList::const_iterator iterLHS = lhsList.begin();
              targetLHSstr = iterLHS->first;
            }
            Word *targetLHS = new Word(true);
            targetLHS->CreateFromString(Output, outputFactorOrder, targetLHSstr, true);
            UTIL_THROW_IF2(targetLHS->GetFactor(0) == NULL,
            		"Null factor left-hand-side");
            targetPhrase.SetTargetLHS(targetLHS);

            // not tested
            Phrase sourcePhrase = this->GetSubString(WordsRange(startPos,endPos-1));

            // get probability
            float probValue = 1;
            if (altProbs.size() > i && altProbs[i].size() > 0) {
              probValue = Scan<float>(altProbs[i]);
            }
            // convert from prob to log-prob
            float scoreValue = FloorScore(TransformScore(probValue));
            targetPhrase.SetXMLScore(scoreValue);
            targetPhrase.Evaluate(sourcePhrase);

            // set span and create XmlOption
            WordsRange range(startPos+1,endPos);
            XmlOption *option = new XmlOption(range,targetPhrase);
            assert(option);
            xmlOptions.push_back(option);

            VERBOSE(2,"xml translation = [" << range << "] " << targetLHSstr << " -> " << altTexts[i] << " prob: " << probValue << endl);
          }
          altTexts.clear();
          altProbs.clear();
        }
      }
    }
  }
  // we are done. check if there are tags that are still open
  if (tagStack.size() > 0) {
    TRACE_ERR("ERROR: some opened tags were never closed: " << line << endl);
    return false;
  }

  // return de-xml'ed sentence in line
  line = cleanLine;
  return true;
}

//! populate this InputType with data from in stream
int TreeInput::Read(std::istream& in,const std::vector<FactorType>& factorOrder)
{
  const StaticData &staticData = StaticData::Instance();

  string line;
  if (getline(in, line, '\n').eof())
    return 0;
  // remove extra spaces
  //line = Trim(line);

  std::vector<XMLParseOutput> sourceLabels;
  ProcessAndStripXMLTags(line, sourceLabels, m_xmlOptions);

  // do words 1st - hack
  stringstream strme;
  strme << line << endl;

  Sentence::Read(strme, factorOrder);

  // size input chart
  size_t sourceSize = GetSize();
  m_sourceChart.resize(sourceSize);

  for (size_t pos = 0; pos < sourceSize; ++pos) {
    m_sourceChart[pos].resize(sourceSize - pos);
  }

  // do source labels
  vector<XMLParseOutput>::const_iterator iterLabel;
  for (iterLabel = sourceLabels.begin(); iterLabel != sourceLabels.end(); ++iterLabel) {
    const XMLParseOutput &labelItem = *iterLabel;
    const WordsRange &range = labelItem.m_range;
    const string &label = labelItem.m_label;
    AddChartLabel(range.GetStartPos() + 1, range.GetEndPos() + 1, label, factorOrder);
  }

  // default label
  for (size_t startPos = 0; startPos < sourceSize; ++startPos) {
    for (size_t endPos = startPos; endPos < sourceSize; ++endPos) {
      NonTerminalSet &list = GetLabelSet(startPos, endPos);
      if (list.size() == 0 || !staticData.GetDefaultNonTermOnlyForEmptyRange()) {
        AddChartLabel(startPos, endPos, staticData.GetInputDefaultNonTerminal(), factorOrder);
      }
    }
  }

  return 1;
}

//! Output debugging info to stream out
void TreeInput::Print(std::ostream &out) const
{
  out << *this << "\n";
}

//! create trans options specific to this InputType
TranslationOptionCollection* TreeInput::CreateTranslationOptionCollection() const
{

  return NULL;
}

void TreeInput::AddChartLabel(size_t startPos, size_t endPos, const Word &label
                              , const std::vector<FactorType>& /* factorOrder */)
{
  UTIL_THROW_IF2(!label.IsNonTerminal(),
		  "Label must be a non-terminal");

  SourceLabelOverlap overlapType = StaticData::Instance().GetSourceLabelOverlap();
  NonTerminalSet &list = GetLabelSet(startPos, endPos);
  switch (overlapType) {
  case SourceLabelOverlapAdd:
    list.insert(label);
    break;
  case SourceLabelOverlapReplace:
    if (list.size() > 0) // replace existing label
      list.clear();
    list.insert(label);
    break;
  case SourceLabelOverlapDiscard:
    if (list.size() == 0)
      list.insert(label);
    break;
  }
}

void TreeInput::AddChartLabel(size_t startPos, size_t endPos, const string &label
                              , const std::vector<FactorType>& factorOrder)
{
  Word word(true);
  const Factor *factor = FactorCollection::Instance().AddFactor(Input, factorOrder[0], label, true); // TODO - no factors
  word.SetFactor(0, factor);

  AddChartLabel(startPos, endPos, word, factorOrder);
}

std::ostream& operator<<(std::ostream &out, const TreeInput &input)
{
  out<< static_cast<Phrase const&>(input) << " ||| ";

  size_t size = input.GetSize();
  for (size_t startPos = 0; startPos < size; ++startPos) {
    for (size_t endPos = startPos; endPos < size; ++endPos) {
      const NonTerminalSet &labelSet = input.GetLabelSet(startPos, endPos);
      NonTerminalSet::const_iterator iter;
      for (iter = labelSet.begin(); iter != labelSet.end(); ++iter) {
        const Word &word = *iter;
        UTIL_THROW_IF2(!word.IsNonTerminal(),
      		  "Word must be a non-terminal");
        out << "[" << startPos <<"," << endPos << "]="
            << word << "(" << word.IsNonTerminal() << ") ";
      }
    }
  }

  return out;
}

} // namespace

<|endoftext|>


<commit_before>/*
*/
#include"ioprocesses.hpp"
#include"variables.hpp"
#include"phandles.hpp"
#include"runsystems.hpp"
#include"types.hpp"

/*
static variables
*/

boost::shared_ptr<Atom> responseatom;

/*-----------------------------------------------------------------------------
CentralIOProcess
-----------------------------------------------------------------------------*/

bool CentralIOProcess::receive(
		boost::shared_ptr<Semispace> sp, Generic* gp) {
	/*insert trylock here, if trylock fails, return false*/
	rcv_queue.push_back(message(sp, gp));
	if(waiting) {
		runsystem->schedule(handle->mypid());
		waiting = 0;
	}
}

/*
1. parse each entry in the receive queue
2. detect if we are the only process running.  If we are, call
   CentralIO::wait(), otherwise just CentralIO::poll()
   2.a. CentralIO should then create responses for requests
        that were processed (e.g. have data, or have some
        error event)
3. collect responses and send to pending processes
   3.a. if the process isn't ready, then keep the response
4. If no responses are pending, check the receive queue.
   If the receive queue is still empty, set our waiting flag
   and return process_waiting
*/
ProcessStatus CentralIOProcess::run(void) {
	/*1*/
	{/*insert trylock here*/
		/*if (trylock.succeeded())*/ {
			/*TODO: parse*/
		}
	}
	/*2*/
	if(runsystem->singleprocess()){
		impl->wait(CentralIOToDo(this));
	} else	impl->poll(CentralIOToDo(this));
	/*3*/
	/*try sending to each process*/
	std::vector<response>::iterator i, to;
	for( i = to = snd_queue.begin(); i != snd_queue.end(); ++i){
		response& curr = *i;
		message& msg = curr.second;
		if(curr.first->pproc->receive(msg.first, msg.second)){
			/*successful send; will get deleted, do nothing*/
		} else {
			/*unsucessful send; move*/
			*to = *i;
			++to;
		}
	}
	snd_queue.erase(to, i);
	/*4*/
	/*check that everything is empty*/
	if(impl->empty() && todo.empty() && snd_queue.empty()) {
		/*insert trylock, if trylock fails, return process_running*/
		if(rcv_queue.empty()) {
			/*now return process_waiting*/
			waiting = 1;
			return process_waiting;
		}
	}
	return process_running;
}

CentralIOProcess* NewCentralIOProcess(void) {
	responseatom = globals->lookup("response");
	return new CentralIOProcess();
}

/*-----------------------------------------------------------------------------
CentralIOToDo
-----------------------------------------------------------------------------*/

/*responses*/

void CentralIOToDo::respond(IOAction io) {
	/*figure out size of response for new semispace*/
	/*3 cons cells, 3 symbols, and one variable data
	(cons (sym respond) (cons (sym ,tag) (cons data (sym nil))))
	*/
	size_t sz = sizeof(Cons) * 3 + sizeof(Sym) * 3;

	/*data response depends on specific action*/
	switch(io.action){
	case ioaction_read:
	case ioaction_write:
		sz += sizeof(BinaryBlob);
		break;
	case ioaction_stdin:
	case ioaction_stdout:
	case ioaction_stderr:
	case ioaction_open:
	case ioaction_server:
	case ioaction_listen:
		sz += sizeof(ArcPortData);
		break;
	case ioaction_system:
		sz += sizeof(Integer);
		break;
	/*these have nil as data*/
	case ioaction_sleep:
	case ioaction_close:
		break;
	}
	boost::shared_ptr<Semispace> ns(new Semispace(sz));
	Semispace& sp = *ns;

	/*build the response*/
	Cons* cp1 = new(sp) Cons();
	cp1->a = new(sp) Sym(responseatom);
	Cons* cp2 = new(sp) Cons();
	cp1->d = cp2;
	cp2->a = new(sp) Sym(io.tag);
	Cons* cp3 = new(sp) Cons();
	cp2->d = cp3;
	cp3->d = new(sp) Sym(NILATOM);

	/*figure out the appropriate data field*/
	switch(io.action){
	case ioaction_read:
	case ioaction_write:
		cp3->a = new(sp) BinaryBlob(*io.data);
		break;
	case ioaction_stdin:
	case ioaction_stdout:
	case ioaction_stderr:
	case ioaction_open:
	case ioaction_server:
	case ioaction_listen:
		cp3->a = new(sp) ArcPortData(io.port);
		break;
	case ioaction_system:
		cp3->a = new(sp) Integer(io.num);
		break;
	/*these have nil as data*/
	case ioaction_sleep:
	case ioaction_close:
		cp3->a = cp3->d;
		break;
	}

	/*now push it onto the send queue*/
	proc->snd_queue.push_back(
		CentralIOProcess::response(
			io.requester,
			CentralIOProcess::message(ns, cp1)
		)
	);
}

<commit_msg>ioprocesses: fixed response(), added error() to CentralIOToDo<commit_after>/*
*/
#include"ioprocesses.hpp"
#include"variables.hpp"
#include"phandles.hpp"
#include"runsystems.hpp"
#include"types.hpp"

/*
static variables
*/

static boost::shared_ptr<Atom> responseatom;
static boost::shared_ptr<Atom> ioatom;
static boost::shared_ptr<Atom> erratom;
static boost::shared_ptr<Atom> eofatom;

/*-----------------------------------------------------------------------------
CentralIOProcess
-----------------------------------------------------------------------------*/

bool CentralIOProcess::receive(
		boost::shared_ptr<Semispace> sp, Generic* gp) {
	/*insert trylock here, if trylock fails, return false*/
	rcv_queue.push_back(message(sp, gp));
	if(waiting) {
		runsystem->schedule(handle->mypid());
		waiting = 0;
	}
}

/*
1. parse each entry in the receive queue
2. detect if we are the only process running.  If we are, call
   CentralIO::wait(), otherwise just CentralIO::poll()
   2.a. CentralIO should then create responses for requests
        that were processed (e.g. have data, or have some
        error event)
3. collect responses and send to pending processes
   3.a. if the process isn't ready, then keep the response
4. If no responses are pending, check the receive queue.
   If the receive queue is still empty, set our waiting flag
   and return process_waiting
*/
ProcessStatus CentralIOProcess::run(void) {
	/*1*/
	{/*insert trylock here*/
		/*if (trylock.succeeded())*/ {
			/*TODO: parse*/
		}
	}
	/*2*/
	if(runsystem->singleprocess()){
		impl->wait(CentralIOToDo(this));
	} else	impl->poll(CentralIOToDo(this));
	/*3*/
	/*try sending to each process*/
	std::vector<response>::iterator i, to;
	for( i = to = snd_queue.begin(); i != snd_queue.end(); ++i){
		response& curr = *i;
		message& msg = curr.second;
		if(curr.first->pproc->receive(msg.first, msg.second)){
			/*successful send; will get deleted, do nothing*/
		} else {
			/*unsucessful send; move*/
			*to = *i;
			++to;
		}
	}
	snd_queue.erase(to, i);
	/*4*/
	/*check that everything is empty*/
	if(impl->empty() && todo.empty() && snd_queue.empty()) {
		/*insert trylock, if trylock fails, return process_running*/
		if(rcv_queue.empty()) {
			/*now return process_waiting*/
			waiting = 1;
			return process_waiting;
		}
	}
	return process_running;
}

CentralIOProcess* NewCentralIOProcess(void) {
	responseatom = globals->lookup("response");
	ioatom = globals->lookup("i/o");
	erratom = globals->lookup("err");
	eofatom = globals->lookup("eof");
	return new CentralIOProcess();
}

/*-----------------------------------------------------------------------------
CentralIOToDo
-----------------------------------------------------------------------------*/

/*responses*/

void CentralIOToDo::respond(IOAction io) {
	/*figure out size of response for new semispace*/
	/*3 cons cells, 3 symbols, and one variable data
	(cons (sym respond) (cons (sym ,tag) (cons data (sym nil))))
	*/
	size_t sz = sizeof(Cons) * 3 + sizeof(Sym) * 3;

	/*data response depends on specific action*/
	switch(io.action){
	case ioaction_read:
	case ioaction_write:
		sz += sizeof(BinaryBlob);
		break;
	case ioaction_stdin:
	case ioaction_stdout:
	case ioaction_stderr:
	case ioaction_open:
	case ioaction_server:
	case ioaction_listen:
		sz += sizeof(ArcPortData);
		break;
	case ioaction_system:
		sz += sizeof(Integer);
		break;
	/*these have nil as data*/
	case ioaction_sleep:
	case ioaction_close:
		break;
	}
	boost::shared_ptr<Semispace> ns(new Semispace(sz));
	Semispace& sp = *ns;

	/*build the response*/
	Cons* cp1 = new(sp) Cons();
	cp1->a = new(sp) Sym(responseatom);
	Cons* cp2 = new(sp) Cons();
	cp1->d = cp2;
	cp2->a = new(sp) Sym(io.tag);
	Cons* cp3 = new(sp) Cons();
	cp2->d = cp3;
	cp3->d = new(sp) Sym(NILATOM);

	/*figure out the appropriate data field*/
	switch(io.action){
	case ioaction_read:
	case ioaction_write:
	{	BinaryBlob* bp = new(sp) BinaryBlob();
		cp3->a = bp;
		bp->pdat = io.data;
	} break;
	case ioaction_stdin:
	case ioaction_stdout:
	case ioaction_stderr:
	case ioaction_open:
	case ioaction_server:
	case ioaction_listen:
		cp3->a = new(sp) ArcPortData(io.port);
		break;
	case ioaction_system:
		cp3->a = new(sp) Integer(io.num);
		break;
	/*these have nil as data*/
	case ioaction_sleep:
	case ioaction_close:
		cp3->a = cp3->d;
		break;
	}

	/*now push it onto the send queue*/
	proc->snd_queue.push_back(
		CentralIOProcess::response(
			io.requester,
			CentralIOProcess::message(ns, cp1)
		)
	);
}

void CentralIOToDo::error(IOAction io, std::string err) {
	/*for now, simply use a symbol with the message*/
	/*TODO: in the future, the error message should be
	a string, not a symbol
	*/
	size_t sz = sizeof(Cons) * 3 + sizeof(Tagged) + sizeof(Sym) * 4
			+ sizeof(Sym);// error object

	boost::shared_ptr<Semispace> ns(new Semispace(sz));
	Semispace& sp = *ns;

	Cons* cp1 = new(sp) Cons();
	cp1->a = new(sp) Sym(erratom);
	Cons* cp2 = new(sp) Cons();
	cp1->d = cp2;
	cp2->a = new(sp) Sym(io.tag);
	Cons* cp3 = new(sp) Cons();
	cp2->d = cp3;
	Tagged* tp = new(sp) Tagged();
	tp->type_o = new(sp) Sym(ioatom);
	tp->rep_o = new(sp) Sym(globals->lookup(err)); // replace in the future
	cp3->a = tp;
	cp3->d = new(sp) Sym(NILATOM);

	/*now push it onto the send queue*/
	proc->snd_queue.push_back(
		CentralIOProcess::response(
			io.requester,
			CentralIOProcess::message(ns, cp1)
		)
	);
}

<|endoftext|>


<commit_before>#include "Angel.h"
#include "mat.h"
#include "vec.h"

#include <stdio.h>
#include <string>
#include <vector>

typedef vec3 color3;
typedef vec4 color4;

//--------------------------------------------------------------------------
//----   CONSTANTS    ------------------------------------------------------
//--------------------------------------------------------------------------

const bool DEBUG = true;

const char *TITLE = "mwa29 - CS537 assignment 5";

const int Xaxis = 0;
const int Yaxis = 1;
const int Zaxis = 2;

const char KEY_XUP       = 'q';
const char KEY_XDOWN     = 'a';
const char KEY_YUP       = 'w';
const char KEY_YDOWN     = 's';
const char KEY_ZUP       = 'e';
const char KEY_ZDOWN     = 'd';
const char KEY_DELTAUP   = 'r';
const char KEY_DELTADOWN = 'f';
const char KEY_RESET     = 't';

const int TRANSFORM_SCALE     = 0;
const int TRANSFORM_ROTATE    = 1;
const int TRANSFORM_TRANSLATE = 2;

const double DELTA_DELTA = 0.01;

const double DEFAULT_DELTA = 0.1;

const char SMF_TYPE_VERTEX = 'v';
const char SMF_TYPE_FACE   = 'f';

//--------------------------------------------------------------------------
//----   GLOBALS      ------------------------------------------------------
//--------------------------------------------------------------------------

int mainWindow;
int menu;
int w = 600, h = 600;

GLint AmbientProduct_loc, DiffuseProduct_loc, SpecularProduct_loc;
GLint ModelView_loc;
GLint Projection_loc;
GLint LightPosition_loc;
GLint Shininess_loc;

std::vector<vec3>   points;
std::vector<vec4>   vertices;
std::vector<vec3>   faces;
std::vector<vec3>   normals;
std::vector<color4> colors;

// Light0
vec4 diffuse0(1.0, 1.0, 1.0, 1.0);
vec4 ambient0(1.0, 1.0, 1.0, 1.0);
vec4 specular0(1.0, 1.0, 1.0, 1.0);
vec4 light0_pos(1.0, 2.0, 3.0);
float shininess = 100.0;

std::string smf_path("models/icos.smf");

double scale_delta     = DEFAULT_DELTA;
double rotate_delta    = DEFAULT_DELTA;
double translate_delta = DEFAULT_DELTA;

vec3 scale_theta(1.0, 1.0, 1.0);
vec3 rotate_theta(0.0, 0.0, 0.0);
vec3 translate_theta(0.0, 0.0, 0.0);

int current_transform = TRANSFORM_TRANSLATE;

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

void
parse_smf(std::string file_path, std::vector<vec3> &vertices, std::vector<vec3> &faces) {
  if (DEBUG) {
    printf("[DEBUG] Parsing smf file: %s\n", file_path.c_str());
  }

  FILE * file;

  file = fopen (file_path.c_str(),"r");
  if (NULL != file) {
    char line[1000];
    while (fgets ( line, sizeof line, file ) != NULL) {
      if (SMF_TYPE_VERTEX == line[0]) {
	double first;
	double second;
	double third;
	sscanf(line, "v %lf %lf %lf\n", &first, &second, &third);
	vertices.push_back(vec3(first, second, third));
      } else if (SMF_TYPE_FACE == line[0]) {
	int first;
	int second;
	int third;
	sscanf(line, "f %d %d %d\n", &first, &second, &third);
	faces.push_back(vec3(first, second, third));
      }
    }
    fclose (file);
  }

  if (DEBUG) {
    printf("[DEBUG] Parse complete.\n");
  }
}

std::vector<vec3>
calculate_normals(std::vector<vec3> vertices, std::vector<vec3> faces)
{
  // n = (p2 - p0) × (p1 - p0)
  std::vector<vec3> normals(vertices.size(), vec3(0.0,0.0,0.0));
  for (uint i = 0; i < faces.size(); i++) {
    GLint index_one   = faces.at(i).x - 1;
    GLint index_two   = faces.at(i).y - 1;
    GLint index_three = faces.at(i).z - 1;

    vec3 p0 = vertices.at(index_one);
    vec3 p1 = vertices.at(index_two);
    vec3 p2 = vertices.at(index_three);

    vec3 n = (p2 - p0) * (p1 - p0);

    normals.at(index_one)   += n;
    normals.at(index_two)   += n;
    normals.at(index_three) += n;
  }

  for (uint i = 0; i < normals.size(); i++) {
    normals.at(i) = normalize(normals.at(i));
  }

  return normals;
}

std::vector<vec4>
get_vertices(std::vector<vec3> points, std::vector<vec3> faces)
{
  if (DEBUG) {
    printf("[DEBUG] Getting vertices.\n");
  }

  std::vector<vec4> vertices;
  for (uint i = 0; i < faces.size(); i++) {
    vertices.push_back(vec4(points.at(faces.at(i).x - 1), 1.0));
    vertices.push_back(vec4(points.at(faces.at(i).y - 1), 1.0));
    vertices.push_back(vec4(points.at(faces.at(i).z - 1), 1.0));
  }

  if (DEBUG) {
    printf("[DEBUG] Vertices gotten: %u.\n", (uint) vertices.size());
  }

  return vertices;
}

void
init( void )
{

  parse_smf(smf_path, points, faces);

  vertices = get_vertices(points, faces);

  normals = calculate_normals(points, faces);

  colors = std::vector<color4>(vertices.size(), color4(1.0,0.0,0.0,1.0));

  if (DEBUG) {
    printf("[DEBUG] printing points.\n");
    for(uint i = 0; i < points.size(); i++) {
      printf("%f, %f, %f\n", points.at(i).x, points.at(i).y, points.at(i).z);
    }
    printf("[DEBUG] printing faces.\n");
    for(uint i = 0; i < faces.size(); i++) {
      printf("%f, %f, %f\n", faces.at(i).x, faces.at(i).y, faces.at(i).z);
    }
    printf("[DEBUG] printing normals.\n");
    for(uint i = 0; i < normals.size(); i++) {
      printf("%f, %f, %f\n", normals.at(i).x, normals.at(i).y, normals.at(i).z);
    }
    printf("[DEBUG] printing vertices.\n");
    for(uint i = 0; i < vertices.size(); i++) {
      printf("%f, %f, %f\n", vertices.at(i).x, vertices.at(i).y, vertices.at(i).z);
      if (2 == i % 3) {
	printf("\n");
      }
    }
    printf("[DEBUG] printing colors.\n");
    for(uint i = 0; i < colors.size(); i++) {
      printf("%f, %f, %f\n", colors.at(i).x, colors.at(i).y, colors.at(i).z);
    }
  }

  // Create a vertex array object
  GLuint vao[1];
  glGenVertexArrays( 1, vao );
  glBindVertexArray( vao[0] );

  // Create and initialize a buffer object
  GLuint buffer;
  glGenBuffers( 1, &buffer );
  glBindBuffer( GL_ARRAY_BUFFER, buffer );
  glBufferData( GL_ARRAY_BUFFER, (vertices.size()*sizeof(vec4)) + (colors.size()*sizeof(color4)),
		NULL, GL_STATIC_DRAW );

  //load data separately
  glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size()*sizeof(vec4), &vertices[0]);
  glBufferSubData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec4),
		  colors.size()*sizeof(color4), &colors[0]);

  // Load shaders and use the resulting shader program
  GLuint program = InitShader( "vshdrcube.glsl", "fshdrcube.glsl" );
  glUseProgram( program );

  // Initialize the vertex position attribute from the vertex shader
  GLuint vPosition_loc = glGetAttribLocation(program, "vPosition");
  glEnableVertexAttribArray(vPosition_loc);
  glVertexAttribPointer(vPosition_loc, 4, GL_FLOAT, GL_FALSE, 0,
			BUFFER_OFFSET(0));
  GLuint vColor_loc = glGetAttribLocation(program, "vColor");
  glEnableVertexAttribArray(vColor_loc);
  glVertexAttribPointer(vColor_loc, 4, GL_FLOAT, GL_FALSE, 0,
			BUFFER_OFFSET(vertices.size()));

  ModelView_loc = glGetUniformLocation( program, "matrix" );

  glClearColor( 1.0, 1.0, 1.0, 1.0 );
}

void
display( void )
{
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  mat4 m(1.0,0.0,0.0,0.0,
	 0.0,1.0,0.0,0.0,
	 0.0,0.0,1.0,0.0,
	 0.0,0.0,0.0,1.0);

  m = m*Translate(translate_theta[Xaxis],
		  translate_theta[Yaxis],
		  translate_theta[Zaxis]);

  m = m*RotateX(rotate_theta[Xaxis]);
  m = m*RotateY(rotate_theta[Yaxis]);
  m = m*RotateZ(rotate_theta[Zaxis]);

  m = m*Scale(scale_theta[Xaxis],
	      scale_theta[Yaxis],
	      scale_theta[Zaxis]);

  glUniformMatrix4fv(ModelView_loc, 1, GL_TRUE, m);

  if (DEBUG) {
    printf("Drawing arrays: %lu\n", vertices.size());
  }
  glDrawArrays( GL_TRIANGLES, 0, vertices.size() );

  glFlush();
  glutSwapBuffers();
}

void
update_theta(int axis, int pos) {
  switch (current_transform) {
  case TRANSFORM_SCALE:     scale_theta[axis]     += pos * scale_delta; break;
  case TRANSFORM_ROTATE:    rotate_theta[axis]    += pos * rotate_delta; break;
  case TRANSFORM_TRANSLATE: translate_theta[axis] += pos * translate_delta; break;
  }
}

void
reset_theta ( void )
{
  scale_theta     = vec3(1.0, 1.0, 1.0);
  rotate_theta    = vec3(0.0, 0.0, 0.0);
  translate_theta = vec3(0.0, 0.0, 0.0);
  scale_delta     = DEFAULT_DELTA;
  rotate_delta    = DEFAULT_DELTA;
  translate_delta = DEFAULT_DELTA;
}

void
update_delta ( int pos )
{
  switch (current_transform) {
  case TRANSFORM_SCALE:     scale_delta     += pos * DELTA_DELTA; break;
  case TRANSFORM_ROTATE:    rotate_delta    += pos * DELTA_DELTA; break;
  case TRANSFORM_TRANSLATE: translate_delta += pos * DELTA_DELTA; break;
  }
}

void
keyboard( unsigned char key, int x, int y )
{
  switch (key) {
  case KEY_XUP:       update_theta(Xaxis,  1); break;
  case KEY_XDOWN:     update_theta(Xaxis, -1); break;
  case KEY_YUP:       update_theta(Yaxis,  1); break;
  case KEY_YDOWN:     update_theta(Yaxis, -1); break;
  case KEY_ZUP:       update_theta(Zaxis,  1); break;
  case KEY_ZDOWN:     update_theta(Zaxis, -1); break;
  case KEY_DELTAUP:   update_delta(1);   break;
  case KEY_DELTADOWN: update_delta(-1);  break;
  case KEY_RESET:     reset_theta(); break;
  }
  glutPostWindowRedisplay(mainWindow);
}

void
processMenuEvents(int menuChoice)
{
  current_transform = menuChoice;
}

void
setupMenu ( void )
{
  glutCreateMenu(processMenuEvents);
  glutAddMenuEntry("Scale",     TRANSFORM_SCALE);
  glutAddMenuEntry("Rotate",    TRANSFORM_ROTATE);
  glutAddMenuEntry("Translate", TRANSFORM_TRANSLATE);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}

void
printHelp ( void ) {
  printf("%s\n", TITLE);
  printf("Keyboard options:\n");
  printf("q - increase x\n");
  printf("a - decrease x\n");
  printf("w - increase y\n");
  printf("s - decrease y\n");
  printf("e - increase z\n");
  printf("d - decrease z\n");
  printf("r - increase delta of currently selected transform\n");
  printf("f - decrease delta of currently selected transform\n");
  printf("t - reset all transformations and deltas\n");
}

int
main( int argc, char **argv )
{
  if (argc > 1) {
    smf_path = std::string(argv[1]);
  }
  printf("%s\n", smf_path.c_str());

  printHelp();

  glutInit( &argc, argv );
  glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
  glutInitWindowPosition(100,100);
  glutInitWindowSize( w, h );

  mainWindow = glutCreateWindow( TITLE );

  glewExperimental=GL_TRUE;
  glewInit();

  init();
  setupMenu();
  glutDisplayFunc ( display  );
  glutKeyboardFunc( keyboard );

  glEnable(GL_DEPTH_TEST);
  glutMainLoop();
  return 0;
}
<commit_msg>Implemented LookAt to spin around the object.<commit_after>#include "Angel.h"
#include "mat.h"
#include "vec.h"

#include <stdio.h>
#include <string>
#include <vector>

typedef vec3 color3;
typedef vec4 color4;

//--------------------------------------------------------------------------
//----   CONSTANTS    ------------------------------------------------------
//--------------------------------------------------------------------------

const bool DEBUG = true;

const char *TITLE = "mwa29 - CS537 assignment 5";

const int Xaxis = 0;
const int Yaxis = 1;
const int Zaxis = 2;

const char KEY_XUP       = 'q';
const char KEY_XDOWN     = 'a';
const char KEY_YUP       = 'w';
const char KEY_YDOWN     = 's';
const char KEY_ZUP       = 'e';
const char KEY_ZDOWN     = 'd';
const char KEY_DELTAUP   = 'r';
const char KEY_DELTADOWN = 'f';
const char KEY_RESET     = 't';

const int TRANSFORM_SCALE     = 0;
const int TRANSFORM_ROTATE    = 1;
const int TRANSFORM_TRANSLATE = 2;

const double DELTA_DELTA = 0.01;

const double DEFAULT_DELTA = 0.1;

const char SMF_TYPE_VERTEX = 'v';
const char SMF_TYPE_FACE   = 'f';

//--------------------------------------------------------------------------
//----   GLOBALS      ------------------------------------------------------
//--------------------------------------------------------------------------

int mainWindow;
int menu;
int w = 600, h = 600;

double t  = 0;   // the time variable
double dt = .005; // the delta for time increment

GLint AmbientProduct_loc, DiffuseProduct_loc, SpecularProduct_loc;
GLint ModelView_loc;
GLint Projection_loc;
GLint LightPosition_loc;
GLint Shininess_loc;

std::vector<vec3>   points;
std::vector<vec4>   vertices;
std::vector<vec3>   faces;
std::vector<vec3>   normals;
std::vector<color4> colors;

// Light0
vec4 diffuse0(1.0, 0.0, 0.0, 1.0);
vec4 ambient0(1.0, 0.0, 0.0, 1.0);
vec4 specular0(1.0, 0.0, 0.0, 1.0);
vec4 light0_pos(1.0, 1.0, 1.0);

// Light1
vec4 diffuse1(0.0, 1.0, 0.0, 1.0);
vec4 ambient1(0.0, 1.0, 0.0, 1.0);
vec4 specular1(0.0, 1.0, 0.0, 1.0);
vec4 light1_pos(-1.0, 1.0, 1.0);

float shininess = 100.0;

std::string smf_path("models/cube.smf");

double scale_delta     = DEFAULT_DELTA;
double rotate_delta    = DEFAULT_DELTA;
double translate_delta = DEFAULT_DELTA;

vec3 scale_theta(1.0, 1.0, 1.0);
vec3 rotate_theta(0.0, 0.0, 0.0);
vec3 translate_theta(0.0, 0.0, 0.0);

int current_transform = TRANSFORM_TRANSLATE;

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

void
parse_smf(std::string file_path, std::vector<vec3> &vertices, std::vector<vec3> &faces) {
  if (DEBUG) {
    printf("[DEBUG] Parsing smf file: %s\n", file_path.c_str());
  }

  FILE * file;

  file = fopen (file_path.c_str(),"r");
  if (NULL != file) {
    char line[1000];
    while (fgets ( line, sizeof line, file ) != NULL) {
      if (SMF_TYPE_VERTEX == line[0]) {
	double first;
	double second;
	double third;
	sscanf(line, "v %lf %lf %lf\n", &first, &second, &third);
	vertices.push_back(vec3(first, second, third));
      } else if (SMF_TYPE_FACE == line[0]) {
	int first;
	int second;
	int third;
	sscanf(line, "f %d %d %d\n", &first, &second, &third);
	faces.push_back(vec3(first, second, third));
      }
    }
    fclose (file);
  }

  if (DEBUG) {
    printf("[DEBUG] Parse complete.\n");
  }
}

std::vector<vec3>
calculate_normals(std::vector<vec3> vertices, std::vector<vec3> faces)
{
  // n = (p2 - p0) × (p1 - p0)
  std::vector<vec3> normals(vertices.size(), vec3(0.0,0.0,0.0));
  for (uint i = 0; i < faces.size(); i++) {
    GLint index_one   = faces.at(i).x - 1;
    GLint index_two   = faces.at(i).y - 1;
    GLint index_three = faces.at(i).z - 1;

    vec3 p0 = vertices.at(index_one);
    vec3 p1 = vertices.at(index_two);
    vec3 p2 = vertices.at(index_three);

    vec3 n = (p2 - p0) * (p1 - p0);

    normals.at(index_one)   += n;
    normals.at(index_two)   += n;
    normals.at(index_three) += n;
  }

  for (uint i = 0; i < normals.size(); i++) {
    normals.at(i) = normalize(normals.at(i));
  }

  return normals;
}

std::vector<vec4>
get_vertices(std::vector<vec3> points, std::vector<vec3> faces)
{
  if (DEBUG) {
    printf("[DEBUG] Getting vertices.\n");
  }

  std::vector<vec4> vertices;
  for (uint i = 0; i < faces.size(); i++) {
    vertices.push_back(vec4(points.at(faces.at(i).x - 1), 1.0));
    vertices.push_back(vec4(points.at(faces.at(i).y - 1), 1.0));
    vertices.push_back(vec4(points.at(faces.at(i).z - 1), 1.0));
  }

  if (DEBUG) {
    printf("[DEBUG] Vertices gotten: %u.\n", (uint) vertices.size());
  }

  return vertices;
}

void
init( void )
{

  parse_smf(smf_path, points, faces);

  vertices = get_vertices(points, faces);

  normals = calculate_normals(points, faces);

  colors = std::vector<color4>(vertices.size(), color4(1.0,0.0,0.0,1.0));

  if (DEBUG) {
    printf("[DEBUG] printing points.\n");
    for(uint i = 0; i < points.size(); i++) {
      printf("%f, %f, %f\n", points.at(i).x, points.at(i).y, points.at(i).z);
    }
    printf("[DEBUG] printing faces.\n");
    for(uint i = 0; i < faces.size(); i++) {
      printf("%f, %f, %f\n", faces.at(i).x, faces.at(i).y, faces.at(i).z);
    }
    printf("[DEBUG] printing normals.\n");
    for(uint i = 0; i < normals.size(); i++) {
      printf("%f, %f, %f\n", normals.at(i).x, normals.at(i).y, normals.at(i).z);
    }
    printf("[DEBUG] printing vertices.\n");
    for(uint i = 0; i < vertices.size(); i++) {
      printf("%f, %f, %f\n", vertices.at(i).x, vertices.at(i).y, vertices.at(i).z);
      if (2 == i % 3) {
	printf("\n");
      }
    }
    printf("[DEBUG] printing colors.\n");
    for(uint i = 0; i < colors.size(); i++) {
      printf("%f, %f, %f\n", colors.at(i).x, colors.at(i).y, colors.at(i).z);
    }
  }

  // Create a vertex array object
  GLuint vao[1];
  glGenVertexArrays( 1, vao );
  glBindVertexArray( vao[0] );

  // Create and initialize a buffer object
  GLuint buffer;
  glGenBuffers( 1, &buffer );
  glBindBuffer( GL_ARRAY_BUFFER, buffer );
  glBufferData( GL_ARRAY_BUFFER, (vertices.size()*sizeof(vec4)) + (colors.size()*sizeof(color4)),
		NULL, GL_STATIC_DRAW );

  //load data separately
  glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size()*sizeof(vec4), &vertices[0]);
  glBufferSubData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec4),
		  colors.size()*sizeof(color4), &colors[0]);

  // Load shaders and use the resulting shader program
  GLuint program = InitShader( "vshdrcube.glsl", "fshdrcube.glsl" );
  glUseProgram( program );

  // Initialize the vertex position attribute from the vertex shader
  GLuint vPosition_loc = glGetAttribLocation(program, "vPosition");
  glEnableVertexAttribArray(vPosition_loc);
  glVertexAttribPointer(vPosition_loc, 4, GL_FLOAT, GL_FALSE, 0,
			BUFFER_OFFSET(0));
  GLuint vColor_loc = glGetAttribLocation(program, "vColor");
  glEnableVertexAttribArray(vColor_loc);
  glVertexAttribPointer(vColor_loc, 4, GL_FLOAT, GL_FALSE, 0,
			BUFFER_OFFSET(vertices.size()));

  ModelView_loc = glGetUniformLocation( program, "matrix" );

  glClearColor( 1.0, 1.0, 1.0, 1.0 );
}

vec4
get_eye() {
  double angle = t;
  return vec4(cos(angle),0.0,sin(angle), 1.0);
}

vec4
get_up( vec4 eye ) {
  return vec4(eye.x, 1.0, eye.z, 1.0);
}

void
display( void )
{
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  mat4 m(1.0,0.0,0.0,0.0,
	 0.0,1.0,0.0,0.0,
	 0.0,0.0,1.0,0.0,
	 0.0,0.0,0.0,1.0);

  // LookAt(eye, at, up)
  vec4 eye = get_eye();
  m = LookAt(eye,
	     vec4(0.0,0.0,0.0,1.0),
	     get_up(eye));

  m = m*Translate(translate_theta[Xaxis],
		  translate_theta[Yaxis],
		  translate_theta[Zaxis]);

  m = m*RotateX(rotate_theta[Xaxis]);
  m = m*RotateY(rotate_theta[Yaxis]);
  m = m*RotateZ(rotate_theta[Zaxis]);

  m = m*Scale(scale_theta[Xaxis],
	      scale_theta[Yaxis],
	      scale_theta[Zaxis]);

  glUniformMatrix4fv(ModelView_loc, 1, GL_TRUE, m);

  if (DEBUG) {
    printf("Drawing arrays: %lu\n", vertices.size());
  }
  glDrawArrays( GL_TRIANGLES, 0, vertices.size() );

  glFlush();
  glutSwapBuffers();
}

void
update_theta(int axis, int pos) {
  switch (current_transform) {
  case TRANSFORM_SCALE:     scale_theta[axis]     += pos * scale_delta; break;
  case TRANSFORM_ROTATE:    rotate_theta[axis]    += pos * rotate_delta; break;
  case TRANSFORM_TRANSLATE: translate_theta[axis] += pos * translate_delta; break;
  }
}

void
reset_theta ( void )
{
  scale_theta     = vec3(1.0, 1.0, 1.0);
  rotate_theta    = vec3(0.0, 0.0, 0.0);
  translate_theta = vec3(0.0, 0.0, 0.0);
  scale_delta     = DEFAULT_DELTA;
  rotate_delta    = DEFAULT_DELTA;
  translate_delta = DEFAULT_DELTA;
}

void
update_delta ( int pos )
{
  switch (current_transform) {
  case TRANSFORM_SCALE:     scale_delta     += pos * DELTA_DELTA; break;
  case TRANSFORM_ROTATE:    rotate_delta    += pos * DELTA_DELTA; break;
  case TRANSFORM_TRANSLATE: translate_delta += pos * DELTA_DELTA; break;
  }
}

void
keyboard( unsigned char key, int x, int y )
{
  switch (key) {
  case KEY_XUP:       update_theta(Xaxis,  1); break;
  case KEY_XDOWN:     update_theta(Xaxis, -1); break;
  case KEY_YUP:       update_theta(Yaxis,  1); break;
  case KEY_YDOWN:     update_theta(Yaxis, -1); break;
  case KEY_ZUP:       update_theta(Zaxis,  1); break;
  case KEY_ZDOWN:     update_theta(Zaxis, -1); break;
  case KEY_DELTAUP:   update_delta(1);   break;
  case KEY_DELTADOWN: update_delta(-1);  break;
  case KEY_RESET:     reset_theta(); break;
  }
  glutPostWindowRedisplay(mainWindow);
}

void
myidle ( void )
{
  t += dt;
  glutPostRedisplay();
}

void
processMenuEvents(int menuChoice)
{
  current_transform = menuChoice;
}

void
setupMenu ( void )
{
  glutCreateMenu(processMenuEvents);
  glutAddMenuEntry("Scale",     TRANSFORM_SCALE);
  glutAddMenuEntry("Rotate",    TRANSFORM_ROTATE);
  glutAddMenuEntry("Translate", TRANSFORM_TRANSLATE);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}

void
printHelp ( void ) {
  printf("%s\n", TITLE);
  printf("Keyboard options:\n");
  printf("q - increase x\n");
  printf("a - decrease x\n");
  printf("w - increase y\n");
  printf("s - decrease y\n");
  printf("e - increase z\n");
  printf("d - decrease z\n");
  printf("r - increase delta of currently selected transform\n");
  printf("f - decrease delta of currently selected transform\n");
  printf("t - reset all transformations and deltas\n");
}

int
main( int argc, char **argv )
{
  if (argc > 1) {
    smf_path = std::string(argv[1]);
  }
  printf("%s\n", smf_path.c_str());

  printHelp();

  glutInit( &argc, argv );
  glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
  glutInitWindowPosition(100,100);
  glutInitWindowSize( w, h );

  mainWindow = glutCreateWindow( TITLE );

  glewExperimental=GL_TRUE;
  glewInit();

  init();
  setupMenu();
  glutDisplayFunc ( display  );
  glutKeyboardFunc( keyboard );
  glutIdleFunc    ( myidle );

  glEnable(GL_DEPTH_TEST);
  glutMainLoop();
  return 0;
}
<|endoftext|>