<commit_before>/*************************************************************************
 *
 *  $RCSfile: chgviset.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-26 18:03:33 $
 *
 *  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 SC_CHGVISET_HXX
#define SC_CHGVISET_HXX

#ifndef _DATETIME_HXX //autogen
#include <tools/datetime.hxx>
#endif

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef SC_RANGELST_HXX
#include "rangelst.hxx"
#endif

enum ScChgsDateMode{    SCDM_DATE_BEFORE=0,SCDM_DATE_SINCE=1,SCDM_DATE_EQUAL=2,
                        SCDM_DATE_NOTEQUAL=3,SCDM_DATE_BETWEEN=4, SCDM_DATE_SAVE=5,
                        SCDM_NO_DATEMODE=6};

namespace utl {
    class TextSearch;
}

class ScDocument;

class ScChangeViewSettings
{
private:

    utl::TextSearch*    pCommentSearcher;
    DateTime            aFirstDateTime;
    DateTime            aLastDateTime;
    String              aAuthorToShow;
    String              aComment;
    ScRangeList         aRangeList;
    ScChgsDateMode      eDateMode;
    BOOL                bShowIt;
    BOOL                bIsDate;
    BOOL                bIsAuthor;
    BOOL                bIsComment;
    BOOL                bIsRange;
    BOOL                bEveryoneButMe;
    BOOL                bShowAccepted;
    BOOL                bShowRejected;

public:

                        ScChangeViewSettings()
                        {
                            pCommentSearcher=NULL;
                            bIsDate=FALSE;
                            bIsAuthor=FALSE;
                            bIsRange=FALSE;
                            bIsComment=FALSE;
                            bShowIt=FALSE;
                            eDateMode=SCDM_DATE_BEFORE;
                            bEveryoneButMe=FALSE;
                            bShowAccepted=FALSE;
                            bShowRejected=FALSE;
                        }

                        ScChangeViewSettings( const ScChangeViewSettings& r );

                        ~ScChangeViewSettings();

    BOOL                ShowChanges() const {return bShowIt;}
    void                SetShowChanges(BOOL nFlag=TRUE){bShowIt=nFlag;}

    BOOL                HasDate() const {return bIsDate;}
    void                SetHasDate(BOOL nFlag=TRUE) {bIsDate=nFlag;}

    void                SetTheDateMode(ScChgsDateMode eDatMod){ eDateMode=eDatMod; }
    ScChgsDateMode      GetTheDateMode() const { return eDateMode; }

    void                SetTheFirstDateTime(const DateTime& aDateTime) {aFirstDateTime=aDateTime;}
    const DateTime&     GetTheFirstDateTime()const {return aFirstDateTime;}

    void                SetTheLastDateTime(const DateTime& aDateTime) {aLastDateTime=aDateTime;}
    const DateTime&     GetTheLastDateTime()const {return aLastDateTime;}

    BOOL                HasAuthor() const {return bIsAuthor;}
    void                SetHasAuthor(BOOL nFlag=TRUE) {bIsAuthor=nFlag;}

    String              GetTheAuthorToShow()const {return aAuthorToShow;}
    void                SetTheAuthorToShow(const String& aString){aAuthorToShow=aString;}

    BOOL                HasComment() const {return bIsComment;}
    void                SetHasComment(BOOL nFlag=TRUE) {bIsComment=nFlag;}

    String              GetTheComment()const {return aComment;}
    void                SetTheComment(const String& aString);

    BOOL                IsValidComment(const String* pCommentStr) const;

    BOOL                IsEveryoneButMe() const {return bEveryoneButMe;}
    void                SetEveryoneButMe(BOOL nFlag=TRUE) {bEveryoneButMe=nFlag;}

    BOOL                HasRange() const {return bIsRange;}
    void                SetHasRange(BOOL nFlag=TRUE) {bIsRange=nFlag;}

    const ScRangeList&  GetTheRangeList()const {return aRangeList;}
    void                SetTheRangeList(const ScRangeList& aRl){aRangeList=aRl;}

    BOOL                IsShowAccepted() const { return bShowAccepted; }
    void                SetShowAccepted( BOOL bVal ) { bShowAccepted = bVal; }

    BOOL                IsShowRejected() const { return bShowRejected; }
    void                SetShowRejected( BOOL bVal ) { bShowRejected = bVal; }

    void                Load( SvStream& rStream, USHORT nVer );
    void                Store( SvStream& rStream ) const;

    ScChangeViewSettings&   operator=   ( const ScChangeViewSettings& r );

                        /// Adjust dates according to selected DateMode
    void                AdjustDateMode( const ScDocument& rDoc );

};

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.798); FILE MERGED 2005/09/05 15:00:36 rt 1.3.798.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: chgviset.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 17:27:10 $
 *
 *  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 SC_CHGVISET_HXX
#define SC_CHGVISET_HXX

#ifndef _DATETIME_HXX //autogen
#include <tools/datetime.hxx>
#endif

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef SC_RANGELST_HXX
#include "rangelst.hxx"
#endif

enum ScChgsDateMode{    SCDM_DATE_BEFORE=0,SCDM_DATE_SINCE=1,SCDM_DATE_EQUAL=2,
                        SCDM_DATE_NOTEQUAL=3,SCDM_DATE_BETWEEN=4, SCDM_DATE_SAVE=5,
                        SCDM_NO_DATEMODE=6};

namespace utl {
    class TextSearch;
}

class ScDocument;

class ScChangeViewSettings
{
private:

    utl::TextSearch*    pCommentSearcher;
    DateTime            aFirstDateTime;
    DateTime            aLastDateTime;
    String              aAuthorToShow;
    String              aComment;
    ScRangeList         aRangeList;
    ScChgsDateMode      eDateMode;
    BOOL                bShowIt;
    BOOL                bIsDate;
    BOOL                bIsAuthor;
    BOOL                bIsComment;
    BOOL                bIsRange;
    BOOL                bEveryoneButMe;
    BOOL                bShowAccepted;
    BOOL                bShowRejected;

public:

                        ScChangeViewSettings()
                        {
                            pCommentSearcher=NULL;
                            bIsDate=FALSE;
                            bIsAuthor=FALSE;
                            bIsRange=FALSE;
                            bIsComment=FALSE;
                            bShowIt=FALSE;
                            eDateMode=SCDM_DATE_BEFORE;
                            bEveryoneButMe=FALSE;
                            bShowAccepted=FALSE;
                            bShowRejected=FALSE;
                        }

                        ScChangeViewSettings( const ScChangeViewSettings& r );

                        ~ScChangeViewSettings();

    BOOL                ShowChanges() const {return bShowIt;}
    void                SetShowChanges(BOOL nFlag=TRUE){bShowIt=nFlag;}

    BOOL                HasDate() const {return bIsDate;}
    void                SetHasDate(BOOL nFlag=TRUE) {bIsDate=nFlag;}

    void                SetTheDateMode(ScChgsDateMode eDatMod){ eDateMode=eDatMod; }
    ScChgsDateMode      GetTheDateMode() const { return eDateMode; }

    void                SetTheFirstDateTime(const DateTime& aDateTime) {aFirstDateTime=aDateTime;}
    const DateTime&     GetTheFirstDateTime()const {return aFirstDateTime;}

    void                SetTheLastDateTime(const DateTime& aDateTime) {aLastDateTime=aDateTime;}
    const DateTime&     GetTheLastDateTime()const {return aLastDateTime;}

    BOOL                HasAuthor() const {return bIsAuthor;}
    void                SetHasAuthor(BOOL nFlag=TRUE) {bIsAuthor=nFlag;}

    String              GetTheAuthorToShow()const {return aAuthorToShow;}
    void                SetTheAuthorToShow(const String& aString){aAuthorToShow=aString;}

    BOOL                HasComment() const {return bIsComment;}
    void                SetHasComment(BOOL nFlag=TRUE) {bIsComment=nFlag;}

    String              GetTheComment()const {return aComment;}
    void                SetTheComment(const String& aString);

    BOOL                IsValidComment(const String* pCommentStr) const;

    BOOL                IsEveryoneButMe() const {return bEveryoneButMe;}
    void                SetEveryoneButMe(BOOL nFlag=TRUE) {bEveryoneButMe=nFlag;}

    BOOL                HasRange() const {return bIsRange;}
    void                SetHasRange(BOOL nFlag=TRUE) {bIsRange=nFlag;}

    const ScRangeList&  GetTheRangeList()const {return aRangeList;}
    void                SetTheRangeList(const ScRangeList& aRl){aRangeList=aRl;}

    BOOL                IsShowAccepted() const { return bShowAccepted; }
    void                SetShowAccepted( BOOL bVal ) { bShowAccepted = bVal; }

    BOOL                IsShowRejected() const { return bShowRejected; }
    void                SetShowRejected( BOOL bVal ) { bShowRejected = bVal; }

    void                Load( SvStream& rStream, USHORT nVer );
    void                Store( SvStream& rStream ) const;

    ScChangeViewSettings&   operator=   ( const ScChangeViewSettings& r );

                        /// Adjust dates according to selected DateMode
    void                AdjustDateMode( const ScDocument& rDoc );

};

#endif

<|endoftext|>


<commit_before>#include "scanner.h"
#include "myexception.h"
#include <QTextStream>
#include <QFile>
#include <QDebug>

Scanner::Scanner(const QString& sourcePath) {
    QFile file(sourcePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        throw MyException(QString("Couldn't not open file %1. Error is : %2.").arg(sourcePath).arg(file.errorString()));

    QTextStream stream(&file);
    fileContent = stream.readAll();
}

QChar Scanner::peek() const {
    return fileContent.at(currentChar);
}

QChar Scanner::next() const {
    return fileContent.at(currentChar + 1);
}

void Scanner::advance() {
    QChar current = peek();
    ++currentChar;
    if (currentChar >= fileContent.length())
        throw MyException("End of file reached");
    if (current == QChar::LineFeed || current == QChar::LineSeparator)
    {
        ++currentLine;
        currentRow = 0;
    }
    else
    {
        ++currentRow;
    }
}

void Scanner::skipComment() {
    //Assumes the first character hasn't been consumed. Expects either "//" or "/*"
    QChar first = peek();
    QChar second = next();
    advance(); advance();

    if (first != '/')
        throw MyException(QString("Error on parsing comment. Line %1, row %2").arg(currentLine).arg(currentRow));

    if (second == '/') //One line comment
    {
        QChar c = peek(); advance();
        do {
            c = peek(); advance();
        } while (c != QChar::LineFeed && c != QChar::LineSeparator);
        return ;
    }
    else if (second == '*')
    {
        QChar c = peek(); advance();
        while (true)
        {
            c = peek(); advance();
            if (c == '*' && peek() == '/')
            {
                advance();
                return;
            }
        }
    }

    throw MyException(QString("Incorrect comment. Character following '/' is %1.").arg(second));
}

Token Scanner::parseCharLiteral() {
    QChar first = peek(); advance();
    QChar second = peek(); advance();
    if (first != '\'')
        throw MyException("Incorrect character literal. Doesn't start with \'");

    if (second == '\\')
        throw MyException("Escaped characters are not implemented yet");

    if (peek() != '\'')
        throw MyException("Incorrect character literal. Doesn't end with \'");

    advance();
    QString lexeme(second);
    return Token(Token::CHAR_LIT, lexeme, second, currentLine, currentRow);

}

Token Scanner::parseStringLiteral() {
    if (peek() != '"')
        throw MyException("String not starting with double quotes");

    advance();
    QString lexeme;
    while (peek() != '"')
    {
        lexeme += peek();
        if (peek() == '\\')
            throw MyException("Escaped characters are not implemented yet");

        advance();
    }
    advance();
    return Token(Token::STR_LIT, lexeme, lexeme, currentLine, currentRow);
}

Token Scanner::parseNumberLiteral() {
    QString lexeme = peek(); advance();
    QChar current = peek();
    bool isInteger = true;
    while (current.isDigit() || current == '.')
    {
        if (current == '.')
            isInteger = false;
        lexeme += current;
        advance();
        current = peek();
    }

    if (isInteger)
        return Token(Token::INT_LIT, lexeme, lexeme.toULongLong(), currentLine, currentRow);
    else
        return Token(Token::DOUBLE_LIT, lexeme, lexeme.toDouble(), currentLine, currentRow);

}

Token Scanner::parseAlphaNum() {
    QString lexeme = peek(); advance();
    QChar current = peek();
    while (current.isDigit() || current.isLetter() || current == '_')
    {
        lexeme += current;
        advance();
        current = peek();
    }

    //TODO : is it a keyword ?
    return Token(Token::IDENTIFIER, lexeme, lexeme, currentLine, currentRow);
}

Token Scanner::nextToken() {
    if (currentChar >= fileContent.length())
        return Token(Token::END_OF_FILE, "EOF", "EOF", currentLine, currentRow);
    QChar firstChar = peek();
    while (firstChar.isSpace()) {
        advance();
        if (currentChar >= fileContent.length())
            return Token(Token::END_OF_FILE, "EOF", "EOF", currentLine, currentRow);
        firstChar = peek();
    }

    if (firstChar.isDigit())
        return parseNumberLiteral();
    else if (firstChar.isLetter() || firstChar == '_')
        return parseAlphaNum();
    else if (firstChar == '"')
        return parseStringLiteral();
    else if (firstChar == '\'')
        return parseCharLiteral();
}
<commit_msg>Partial implementation of nextToken()<commit_after>#include "scanner.h"
#include "myexception.h"
#include <QTextStream>
#include <QFile>
#include <QDebug>

Scanner::Scanner(const QString& sourcePath) {
    QFile file(sourcePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        throw MyException(QString("Couldn't not open file %1. Error is : %2.").arg(sourcePath).arg(file.errorString()));

    QTextStream stream(&file);
    fileContent = stream.readAll();
}

QChar Scanner::peek() const {
    return fileContent.at(currentChar);
}

QChar Scanner::next() const {
    return fileContent.at(currentChar + 1);
}

void Scanner::advance() {
    QChar current = peek();
    ++currentChar;
    if (currentChar >= fileContent.length())
        throw MyException("End of file reached");
    if (current == QChar::LineFeed || current == QChar::LineSeparator)
    {
        ++currentLine;
        currentRow = 0;
    }
    else
    {
        ++currentRow;
    }
}

void Scanner::skipComment() {
    //Assumes the first character hasn't been consumed. Expects either "//" or "/*"
    QChar first = peek();
    QChar second = next();
    advance(); advance();

    if (first != '/')
        throw MyException(QString("Error on parsing comment. Line %1, row %2").arg(currentLine).arg(currentRow));

    if (second == '/') //One line comment
    {
        QChar c = peek(); advance();
        do {
            c = peek(); advance();
        } while (c != QChar::LineFeed && c != QChar::LineSeparator);
        return ;
    }
    else if (second == '*')
    {
        QChar c = peek(); advance();
        while (true)
        {
            c = peek(); advance();
            if (c == '*' && peek() == '/')
            {
                advance();
                return;
            }
        }
    }

    throw MyException(QString("Incorrect comment. Character following '/' is %1.").arg(second));
}

Token Scanner::parseCharLiteral() {
    QChar first = peek(); advance();
    QChar second = peek(); advance();
    if (first != '\'')
        throw MyException("Incorrect character literal. Doesn't start with \'");

    if (second == '\\')
        throw MyException("Escaped characters are not implemented yet");

    if (peek() != '\'')
        throw MyException("Incorrect character literal. Doesn't end with \'");

    advance();
    QString lexeme(second);
    return Token(Token::CHAR_LIT, lexeme, second, currentLine, currentRow);

}

Token Scanner::parseStringLiteral() {
    if (peek() != '"')
        throw MyException("String not starting with double quotes");

    advance();
    QString lexeme;
    while (peek() != '"')
    {
        lexeme += peek();
        if (peek() == '\\')
            throw MyException("Escaped characters are not implemented yet");

        advance();
    }
    advance();
    return Token(Token::STR_LIT, lexeme, lexeme, currentLine, currentRow);
}

Token Scanner::parseNumberLiteral() {
    QString lexeme = peek(); advance();
    QChar current = peek();
    bool isInteger = true;
    while (current.isDigit() || current == '.')
    {
        if (current == '.')
            isInteger = false;
        lexeme += current;
        advance();
        current = peek();
    }

    if (isInteger)
        return Token(Token::INT_LIT, lexeme, lexeme.toULongLong(), currentLine, currentRow);
    else
        return Token(Token::DOUBLE_LIT, lexeme, lexeme.toDouble(), currentLine, currentRow);

}

Token Scanner::parseAlphaNum() {
    QString lexeme = peek(); advance();
    QChar current = peek();
    while (current.isDigit() || current.isLetter() || current == '_')
    {
        lexeme += current;
        advance();
        current = peek();
    }

    //TODO : is it a keyword ?
    return Token(Token::IDENTIFIER, lexeme, lexeme, currentLine, currentRow);
}

Token Scanner::nextToken() {
    if (currentChar >= fileContent.length())
        return Token(Token::END_OF_FILE, "EOF", "EOF", currentLine, currentRow);
    QChar firstChar = peek();
    while (firstChar.isSpace()) {
        advance();
        if (currentChar >= fileContent.length())
            return Token(Token::END_OF_FILE, "EOF", "EOF", currentLine, currentRow);
        firstChar = peek();
    }

    if (firstChar.isDigit())
        return parseNumberLiteral();
    else if (firstChar.isLetter() || firstChar == '_')
        return parseAlphaNum();
    else if (firstChar == '"')
        return parseStringLiteral();
    else if (firstChar == '\'')
        return parseCharLiteral();
    else if (firstChar == '/') {
        if (next() == '*' || next() == '/')
        {
            skipComment();
            return nextToken();
        }
        else throw MyException("Division unimplemented yet : '/' should only be used for comments");
    }
    else if (firstChar == '(') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        return Token(Token::LEFT_PAREN, "(", "(", l, r);
    }
    else if (firstChar == ')') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        return Token(Token::RIGHT_PARENT, ")", ")", l, r);
    }
    else if (firstChar == '{') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        return Token(Token::LEFT_BRACKET, "{", "{", l, r);
    }
    else if (firstChar == '}') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        return Token(Token::RIGHT_BRACKET, "}", "}", l, r);
    }
    else if (firstChar == '[') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        return Token(Token::LEFT_SQUARE_BRACKET, "[", "[", l, r);
    }
    else if (firstChar == ']') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        return Token(Token::RIGHT_SQUARE_BRACKET, "[", "]", l, r);
    }
    else if (firstChar == '<') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        if (peek() == '=') {
            advance();
            return Token(Token::LET, "<=", "<=", l, r);
        }
        else
            return Token(Token::LT, "<", "<", l, r);
    }
    else if (firstChar == '>') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        if (peek() == '=') {
            advance();
            return Token(Token::GET, ">=", ">=", l, r);
        }
        else
            return Token(Token::GT, ">", ">", l, r);
    }
    else if (firstChar == '=') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        if (peek() == '=') {
            advance();
            return Token(Token::EQ, "==", "==", l, r);
        }
        else
            return Token(Token::EQUAL, "=", "=", l, r);
    }
    else if (firstChar == '!') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        if (peek() == '=') {
            advance();
            return Token(Token::NEQ, "!=", "!=", l, r);
        }
        else
            return Token(Token::NOT, "!", "!", l, r);
    }
    else if (firstChar == ';') {
        auto l = currentLine;
        auto r = currentRow;
        advance();
        return Token(Token::SEMICOLON, ";", ";", l, r);
    }
    else if (firstChar == '-') {
        if (next() == '>') {
            auto l = currentLine;
            auto r = currentRow;
            advance(); advance(); return Token(Token::ARROW, "->", "->", l, r);
        }
        else {
            //TODO : implement -=
            auto l = currentLine;
            auto r = currentRow;
            advance();
            return Token(Token::MINUS, "-", "-", l, r);
        }
    }

    throw MyException(QString("Parse error... Line is %1, row is %2.").arg(currentLine).arg(currentRow));
}
<|endoftext|>


<commit_before><<<<<<< HEAD
#include "MetaballsExample.h"

#include <glm/gtc/constants.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <glbinding/gl/enum.h>
#include <glbinding/gl/bitfield.h>

#include <globjects/globjects.h>
#include <globjects/logging.h>
#include <globjects/DebugMessage.h>

#include <widgetzeug/make_unique.hpp>

#include <gloperate/base/RenderTargetType.h>

#include <gloperate/painter/TargetFramebufferCapability.h>
#include <gloperate/painter/ViewportCapability.h>
#include <gloperate/painter/PerspectiveProjectionCapability.h>
#include <gloperate/painter/CameraCapability.h>
#include <gloperate/painter/VirtualTimeCapability.h>

#include <globjects/Texture.h>
#include <globjects/AttachedTexture.h>

#include "OtherRenderer.h"
#include "RaycastingRenderer.h"
#include "ScreenSpaceFluidRenderer.h"

MetaballsExample::MetaballsExample(gloperate::ResourceManager & resourceManager)
:   Painter(resourceManager)
,   m_targetFramebufferCapability(addCapability(new gloperate::TargetFramebufferCapability()))
,   m_viewportCapability(addCapability(new gloperate::ViewportCapability()))
,   m_projectionCapability(addCapability(new gloperate::PerspectiveProjectionCapability(m_viewportCapability)))
,   m_cameraCapability(addCapability(new gloperate::CameraCapability()))
,	m_raycasting(true)
,   m_SSF(false)
{
	setupPropertyGroup();
}

MetaballsExample::~MetaballsExample() = default;

void MetaballsExample::setupProjection()
{
    //static const auto zNear = 0.3f, zFar = 15.f, fovy = 50.f;
}

void MetaballsExample::onInitialize()
{
    globjects::init();

#ifdef __APPLE__
    globjects::Shader::clearGlobalReplacements();
    globjects::Shader::globalReplace("#version 140", "#version 150");

    globjects::debug() << "Using global OS X shader replacement '#version 140' -> '#version 150'" << std::endl;
#endif
	gl::glClearColor(0.0, 0.0, 0.0, 1.0);

    m_texture = new globjects::Texture;
    m_texture->image2D(0, gl::GL_RGBA, m_viewportCapability->width(), m_viewportCapability->height(), 0, gl::GL_RGBA, gl::GL_UNSIGNED_BYTE, nullptr);

    m_fbo = new globjects::Framebuffer;
    m_fbo->attachTexture(gl::GL_COLOR_ATTACHMENT0, m_texture, 0);

<<<<<<< HEAD
    gl::glClearColor(0.0, 0.0, 0.0, 1.0);
=======
	//m_vertices = new globjects::Buffer;
	//m_vertices->setData(std::vector<float>{
	//	-1.f, 1.f,
	//	-1.f, -1.f,
	//	1.f, 1.f,
	//	1.f, -1.f
	//}, gl::GL_STATIC_DRAW);
	for (int i = 0; i < METABALLSCOUNT; i++)
		m_metaballs[i] = glm::vec4(i * 2.f, 0.f, 0.f, 0.5f);

	m_vao = new globjects::VertexArray;

	auto binding = m_vao->binding(0);
	binding->setAttribute(0);
	binding->setBuffer(m_metaballs.data, 0, 4 * sizeof(float));
	binding->setFormat(4, gl::GL_FLOAT);

	m_vao->enable(0);

    gl::glClearColor(1.0, 1.0, 1.0, 1.0);
>>>>>>> DOESN'T WORK Merge commit

    m_fbo->unbind();

<<<<<<< HEAD
	m_otherRenderer = std::make_unique<OtherRenderer>();
	m_rayRenderer = std::make_unique<RaycastingRenderer>();
=======
	m_rayRenderer = std::make_unique<RaycastingRenderer>(m_viewportCapability, m_projectionCapability, m_cameraCapability);
	m_SSFRenderer = std::make_unique<ScreenSpaceFluidRenderer>(m_viewportCapability, m_projectionCapability, m_cameraCapability);
>>>>>>> initialize ScreenSpaceFluidRenderer

	m_SSFRenderer->initialize();
	m_rayRenderer->initialize();
}

void MetaballsExample::onPaint()
{
	m_fluidSimulator.update();

	if (m_viewportCapability->hasChanged())
	{
		m_texture->image2D(0, gl::GL_RGBA, m_viewportCapability->width(), m_viewportCapability->height(), 0, gl::GL_RGBA, gl::GL_UNSIGNED_BYTE, nullptr);

		m_viewportCapability->setChanged(false);
	}

	gl::glViewport(0, 0, m_viewportCapability->width(), m_viewportCapability->height());
	gl::glClear(gl::GL_COLOR_BUFFER_BIT);

	m_fbo->bind();

	std::array<int, 4> rect = { { 0, 0, m_viewportCapability->width(), m_viewportCapability->height() } };

	globjects::Framebuffer * targetFBO = m_targetFramebufferCapability->framebuffer() ? m_targetFramebufferCapability->framebuffer() : globjects::Framebuffer::defaultFBO();

	if (m_raycasting)
<<<<<<< HEAD
<<<<<<< HEAD
	{
		m_rayRenderer->draw(this);
=======
	{

		m_rayRenderer->computePhysiks();
		m_rayRenderer->draw(m_vao);
>>>>>>> initialize ScreenSpaceFluidRenderer
=======

	{
<<<<<<< HEAD
		gl::glClear(gl::GL_COLOR_BUFFER_BIT);
		m_rayRenderer->draw(this);
>>>>>>> fixed merge issues & initialize SSFR
=======
		m_rayRenderer->draw(this, m_fluidSimulator.metaballs());
>>>>>>> Physik im raycast Renderer eingebunden

		targetFBO->bind(gl::GL_DRAW_FRAMEBUFFER);
		m_fbo->blit(gl::GL_COLOR_ATTACHMENT0, rect, targetFBO, gl::GL_BACK_LEFT, rect, gl::GL_COLOR_BUFFER_BIT, gl::GL_LINEAR);
	}
	if (m_SSF)
	{
		gl::glClear(gl::GL_COLOR_BUFFER_BIT);
		rect[0] += m_raycasting * static_cast<unsigned>(m_viewportCapability->width() / 2);
<<<<<<< HEAD

<<<<<<< HEAD
<<<<<<< HEAD
		m_otherRenderer->draw(this);
=======
		m_SSFRenderer->draw(m_vao);
>>>>>>> initialize ScreenSpaceFluidRenderer
=======

		m_SSFRenderer->draw(this);
>>>>>>> fixed merge issues & initialize SSFR
=======
		m_otherRenderer->draw(this, m_fluidSimulator.metaballs());
>>>>>>> Physik im raycast Renderer eingebunden

		targetFBO->bind(gl::GL_DRAW_FRAMEBUFFER);
		m_fbo->blit(gl::GL_COLOR_ATTACHMENT0, rect, targetFBO, gl::GL_BACK_LEFT, rect, gl::GL_COLOR_BUFFER_BIT, gl::GL_LINEAR);
	}

	globjects::Framebuffer::unbind();
}

bool MetaballsExample::getRaycasting() const
{
	return m_raycasting;
}

void MetaballsExample::setRaycasting(bool value)
{
	m_raycasting = value;
	//m_other = !m_raycasting;
}

bool MetaballsExample::getSSF() const
{
	return m_SSF;
}

void MetaballsExample::setSSF(bool value)
{
	m_SSF = value;
	//m_other = !m_raycasting;
}

void MetaballsExample::setupPropertyGroup()
{
	addProperty<bool>("Raycasting", this,
		&MetaballsExample::getRaycasting, &MetaballsExample::setRaycasting);
<<<<<<< HEAD
<<<<<<< HEAD
	addProperty<bool>("Other", this,
		&MetaballsExample::getOther, &MetaballsExample::setOther);
=======

	addProperty<bool>("ScreenSpaceFluid", this,
		&MetaballsExample::getSSF, &MetaballsExample::setSSF);

>>>>>>> fixed merge issues & initialize SSFR
}

const gloperate::AbstractTargetFramebufferCapability * MetaballsExample::targetFramebufferCapability() const
{
	return m_targetFramebufferCapability;
}

const gloperate::AbstractViewportCapability * MetaballsExample::viewportCapability() const
{
	return m_viewportCapability;
}

const gloperate::AbstractPerspectiveProjectionCapability * MetaballsExample::projectionCapability() const
{
	return m_projectionCapability;
}

const gloperate::AbstractCameraCapability * MetaballsExample::cameraCapability() const
{
	return m_cameraCapability;
<<<<<<< HEAD
}

const std::array<glm::vec4, METABALLSCOUNT> & MetaballsExample::metaballs() const
{
	return m_metaballs;
<<<<<<< HEAD
=======
	addProperty<bool>("ScreenSpaceFluid", this,
		&MetaballsExample::getSSF, &MetaballsExample::setSSF);
>>>>>>> initialize ScreenSpaceFluidRenderer
=======

>>>>>>> fixed merge issues & initialize SSFR
=======
>>>>>>> Physik im raycast Renderer eingebunden
=======
#include "MetaballsExample.h"

#include <glm/gtc/constants.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <glbinding/gl/enum.h>
#include <glbinding/gl/bitfield.h>

#include <globjects/globjects.h>
#include <globjects/logging.h>
#include <globjects/DebugMessage.h>

#include <widgetzeug/make_unique.hpp>

#include <gloperate/base/RenderTargetType.h>

#include <gloperate/painter/TargetFramebufferCapability.h>
#include <gloperate/painter/ViewportCapability.h>
#include <gloperate/painter/PerspectiveProjectionCapability.h>
#include <gloperate/painter/CameraCapability.h>
#include <gloperate/painter/VirtualTimeCapability.h>

#include <globjects/Texture.h>
#include <globjects/AttachedTexture.h>

#include "OtherRenderer.h"
#include "RaycastingRenderer.h"

MetaballsExample::MetaballsExample(gloperate::ResourceManager & resourceManager)
:   Painter(resourceManager)
,   m_targetFramebufferCapability(addCapability(new gloperate::TargetFramebufferCapability()))
,   m_viewportCapability(addCapability(new gloperate::ViewportCapability()))
,   m_projectionCapability(addCapability(new gloperate::PerspectiveProjectionCapability(m_viewportCapability)))
,   m_cameraCapability(addCapability(new gloperate::CameraCapability()))
,	m_raycasting(true)
,	m_other(false)
{
	setupPropertyGroup();
}

MetaballsExample::~MetaballsExample() = default;

void MetaballsExample::setupProjection()
{
    //static const auto zNear = 0.3f, zFar = 15.f, fovy = 50.f;
}

void MetaballsExample::onInitialize()
{
    globjects::init();

#ifdef __APPLE__
    globjects::Shader::clearGlobalReplacements();
    globjects::Shader::globalReplace("#version 140", "#version 150");

    globjects::debug() << "Using global OS X shader replacement '#version 140' -> '#version 150'" << std::endl;
#endif
	gl::glClearColor(0.0, 0.0, 0.0, 1.0);

    m_texture = new globjects::Texture;
    m_texture->image2D(0, gl::GL_RGBA, m_viewportCapability->width(), m_viewportCapability->height(), 0, gl::GL_RGBA, gl::GL_UNSIGNED_BYTE, nullptr);

    m_fbo = new globjects::Framebuffer;
    m_fbo->attachTexture(gl::GL_COLOR_ATTACHMENT0, m_texture, 0);

    gl::glClearColor(0.0, 0.0, 0.0, 1.0);

    m_fbo->unbind();

	m_otherRenderer = std::make_unique<OtherRenderer>();
	m_rayRenderer = std::make_unique<RaycastingRenderer>();

	m_otherRenderer->initialize();
	m_rayRenderer->initialize();
}

void MetaballsExample::onPaint()
{
	m_fluidSimulator.update();

	if (m_viewportCapability->hasChanged())
	{
		m_texture->image2D(0, gl::GL_RGBA, m_viewportCapability->width(), m_viewportCapability->height(), 0, gl::GL_RGBA, gl::GL_UNSIGNED_BYTE, nullptr);

		m_viewportCapability->setChanged(false);
	}

	gl::glViewport(0, 0, m_viewportCapability->width(), m_viewportCapability->height());
	gl::glClear(gl::GL_COLOR_BUFFER_BIT);

	m_fbo->bind();
	gl::glClear(gl::GL_COLOR_BUFFER_BIT);

	std::array<int, 4> rect = { { 0, 0, m_viewportCapability->width(), m_viewportCapability->height() } };

	globjects::Framebuffer * targetFBO = m_targetFramebufferCapability->framebuffer() ? m_targetFramebufferCapability->framebuffer() : globjects::Framebuffer::defaultFBO();

	if (m_raycasting)
	{
		m_rayRenderer->draw(this, m_fluidSimulator.metaballs());

		targetFBO->bind(gl::GL_DRAW_FRAMEBUFFER);
		m_fbo->blit(gl::GL_COLOR_ATTACHMENT0, rect, targetFBO, gl::GL_BACK_LEFT, rect, gl::GL_COLOR_BUFFER_BIT, gl::GL_LINEAR);
	}
	if (m_other)
	{
		rect[0] += m_raycasting * static_cast<unsigned>(m_viewportCapability->width() / 2);

		m_otherRenderer->draw(this, m_fluidSimulator.metaballs());

		targetFBO->bind(gl::GL_DRAW_FRAMEBUFFER);
		m_fbo->blit(gl::GL_COLOR_ATTACHMENT0, rect, targetFBO, gl::GL_BACK_LEFT, rect, gl::GL_COLOR_BUFFER_BIT, gl::GL_LINEAR);
	}

	globjects::Framebuffer::unbind();
}

bool MetaballsExample::getRaycasting() const
{
	return m_raycasting;
}

void MetaballsExample::setRaycasting(bool value)
{
	m_raycasting = value;
	//m_other = !m_raycasting;
}

bool MetaballsExample::getOther() const
{
	return m_other;
}

void MetaballsExample::setOther(bool value)
{
	m_other = value;
	//m_raycasting = !m_other;
}

void MetaballsExample::setupPropertyGroup()
{
	addProperty<bool>("Raycasting", this,
		&MetaballsExample::getRaycasting, &MetaballsExample::setRaycasting);
	addProperty<bool>("Other", this,
		&MetaballsExample::getOther, &MetaballsExample::setOther);
}

const gloperate::AbstractTargetFramebufferCapability * MetaballsExample::targetFramebufferCapability() const
{
	return m_targetFramebufferCapability;
}

const gloperate::AbstractViewportCapability * MetaballsExample::viewportCapability() const
{
	return m_viewportCapability;
}

const gloperate::AbstractPerspectiveProjectionCapability * MetaballsExample::projectionCapability() const
{
	return m_projectionCapability;
}

const gloperate::AbstractCameraCapability * MetaballsExample::cameraCapability() const
{
	return m_cameraCapability;
>>>>>>> added environment map
}<commit_msg>fixed merge conflict<commit_after><<<<<<< HEAD
<<<<<<< HEAD
#include "MetaballsExample.h"

#include <glm/gtc/constants.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <glbinding/gl/enum.h>
#include <glbinding/gl/bitfield.h>

#include <globjects/globjects.h>
#include <globjects/logging.h>
#include <globjects/DebugMessage.h>

#include <widgetzeug/make_unique.hpp>

#include <gloperate/base/RenderTargetType.h>

#include <gloperate/painter/TargetFramebufferCapability.h>
#include <gloperate/painter/ViewportCapability.h>
#include <gloperate/painter/PerspectiveProjectionCapability.h>
#include <gloperate/painter/CameraCapability.h>
#include <gloperate/painter/VirtualTimeCapability.h>

#include <globjects/Texture.h>
#include <globjects/AttachedTexture.h>

#include "OtherRenderer.h"
#include "RaycastingRenderer.h"
#include "ScreenSpaceFluidRenderer.h"

MetaballsExample::MetaballsExample(gloperate::ResourceManager & resourceManager)
:   Painter(resourceManager)
,   m_targetFramebufferCapability(addCapability(new gloperate::TargetFramebufferCapability()))
,   m_viewportCapability(addCapability(new gloperate::ViewportCapability()))
,   m_projectionCapability(addCapability(new gloperate::PerspectiveProjectionCapability(m_viewportCapability)))
,   m_cameraCapability(addCapability(new gloperate::CameraCapability()))
,	m_raycasting(true)
,   m_SSF(false)
{
	setupPropertyGroup();
}

MetaballsExample::~MetaballsExample() = default;

void MetaballsExample::setupProjection()
{
    //static const auto zNear = 0.3f, zFar = 15.f, fovy = 50.f;
}

void MetaballsExample::onInitialize()
{
    globjects::init();

#ifdef __APPLE__
    globjects::Shader::clearGlobalReplacements();
    globjects::Shader::globalReplace("#version 140", "#version 150");

    globjects::debug() << "Using global OS X shader replacement '#version 140' -> '#version 150'" << std::endl;
#endif
	gl::glClearColor(0.0, 0.0, 0.0, 1.0);

    m_texture = new globjects::Texture;
    m_texture->image2D(0, gl::GL_RGBA, m_viewportCapability->width(), m_viewportCapability->height(), 0, gl::GL_RGBA, gl::GL_UNSIGNED_BYTE, nullptr);

    m_fbo = new globjects::Framebuffer;
    m_fbo->attachTexture(gl::GL_COLOR_ATTACHMENT0, m_texture, 0);

<<<<<<< HEAD
    gl::glClearColor(0.0, 0.0, 0.0, 1.0);
=======
	//m_vertices = new globjects::Buffer;
	//m_vertices->setData(std::vector<float>{
	//	-1.f, 1.f,
	//	-1.f, -1.f,
	//	1.f, 1.f,
	//	1.f, -1.f
	//}, gl::GL_STATIC_DRAW);
	for (int i = 0; i < METABALLSCOUNT; i++)
		m_metaballs[i] = glm::vec4(i * 2.f, 0.f, 0.f, 0.5f);

	m_vao = new globjects::VertexArray;

	auto binding = m_vao->binding(0);
	binding->setAttribute(0);
	binding->setBuffer(m_metaballs.data, 0, 4 * sizeof(float));
	binding->setFormat(4, gl::GL_FLOAT);

	m_vao->enable(0);

    gl::glClearColor(1.0, 1.0, 1.0, 1.0);
>>>>>>> DOESN'T WORK Merge commit

    m_fbo->unbind();

<<<<<<< HEAD
	m_otherRenderer = std::make_unique<OtherRenderer>();
	m_rayRenderer = std::make_unique<RaycastingRenderer>();
=======
	m_rayRenderer = std::make_unique<RaycastingRenderer>(m_viewportCapability, m_projectionCapability, m_cameraCapability);
	m_SSFRenderer = std::make_unique<ScreenSpaceFluidRenderer>(m_viewportCapability, m_projectionCapability, m_cameraCapability);
>>>>>>> initialize ScreenSpaceFluidRenderer

	m_SSFRenderer->initialize();
	m_rayRenderer->initialize();
}

void MetaballsExample::onPaint()
{
	m_fluidSimulator.update();

	if (m_viewportCapability->hasChanged())
	{
		m_texture->image2D(0, gl::GL_RGBA, m_viewportCapability->width(), m_viewportCapability->height(), 0, gl::GL_RGBA, gl::GL_UNSIGNED_BYTE, nullptr);

		m_viewportCapability->setChanged(false);
	}

	gl::glViewport(0, 0, m_viewportCapability->width(), m_viewportCapability->height());
	gl::glClear(gl::GL_COLOR_BUFFER_BIT);

	m_fbo->bind();

	std::array<int, 4> rect = { { 0, 0, m_viewportCapability->width(), m_viewportCapability->height() } };

	globjects::Framebuffer * targetFBO = m_targetFramebufferCapability->framebuffer() ? m_targetFramebufferCapability->framebuffer() : globjects::Framebuffer::defaultFBO();

	if (m_raycasting)
<<<<<<< HEAD
<<<<<<< HEAD
	{
		m_rayRenderer->draw(this);
=======
	{

		m_rayRenderer->computePhysiks();
		m_rayRenderer->draw(m_vao);
>>>>>>> initialize ScreenSpaceFluidRenderer
=======

	{
<<<<<<< HEAD
		gl::glClear(gl::GL_COLOR_BUFFER_BIT);
		m_rayRenderer->draw(this);
>>>>>>> fixed merge issues & initialize SSFR
=======
		m_rayRenderer->draw(this, m_fluidSimulator.metaballs());
>>>>>>> Physik im raycast Renderer eingebunden

		targetFBO->bind(gl::GL_DRAW_FRAMEBUFFER);
		m_fbo->blit(gl::GL_COLOR_ATTACHMENT0, rect, targetFBO, gl::GL_BACK_LEFT, rect, gl::GL_COLOR_BUFFER_BIT, gl::GL_LINEAR);
	}
	if (m_SSF)
	{
		gl::glClear(gl::GL_COLOR_BUFFER_BIT);
		rect[0] += m_raycasting * static_cast<unsigned>(m_viewportCapability->width() / 2);
<<<<<<< HEAD

<<<<<<< HEAD
<<<<<<< HEAD
		m_otherRenderer->draw(this);
=======
		m_SSFRenderer->draw(m_vao);
>>>>>>> initialize ScreenSpaceFluidRenderer
=======

		m_SSFRenderer->draw(this);
>>>>>>> fixed merge issues & initialize SSFR
=======
		m_otherRenderer->draw(this, m_fluidSimulator.metaballs());
>>>>>>> Physik im raycast Renderer eingebunden

		targetFBO->bind(gl::GL_DRAW_FRAMEBUFFER);
		m_fbo->blit(gl::GL_COLOR_ATTACHMENT0, rect, targetFBO, gl::GL_BACK_LEFT, rect, gl::GL_COLOR_BUFFER_BIT, gl::GL_LINEAR);
	}

	globjects::Framebuffer::unbind();
}

bool MetaballsExample::getRaycasting() const
{
	return m_raycasting;
}

void MetaballsExample::setRaycasting(bool value)
{
	m_raycasting = value;
	//m_other = !m_raycasting;
}

bool MetaballsExample::getSSF() const
{
	return m_SSF;
}

void MetaballsExample::setSSF(bool value)
{
	m_SSF = value;
	//m_other = !m_raycasting;
}

void MetaballsExample::setupPropertyGroup()
{
	addProperty<bool>("Raycasting", this,
		&MetaballsExample::getRaycasting, &MetaballsExample::setRaycasting);
<<<<<<< HEAD
<<<<<<< HEAD
	addProperty<bool>("Other", this,
		&MetaballsExample::getOther, &MetaballsExample::setOther);
=======

	addProperty<bool>("ScreenSpaceFluid", this,
		&MetaballsExample::getSSF, &MetaballsExample::setSSF);

>>>>>>> fixed merge issues & initialize SSFR
}

const gloperate::AbstractTargetFramebufferCapability * MetaballsExample::targetFramebufferCapability() const
{
	return m_targetFramebufferCapability;
}

const gloperate::AbstractViewportCapability * MetaballsExample::viewportCapability() const
{
	return m_viewportCapability;
}

const gloperate::AbstractPerspectiveProjectionCapability * MetaballsExample::projectionCapability() const
{
	return m_projectionCapability;
}

const gloperate::AbstractCameraCapability * MetaballsExample::cameraCapability() const
{
	return m_cameraCapability;
<<<<<<< HEAD
}

const std::array<glm::vec4, METABALLSCOUNT> & MetaballsExample::metaballs() const
{
	return m_metaballs;
<<<<<<< HEAD
=======
	addProperty<bool>("ScreenSpaceFluid", this,
		&MetaballsExample::getSSF, &MetaballsExample::setSSF);
>>>>>>> initialize ScreenSpaceFluidRenderer
=======

>>>>>>> fixed merge issues & initialize SSFR
=======
>>>>>>> Physik im raycast Renderer eingebunden
=======
=======
>>>>>>> fixed merge conflict
#include "MetaballsExample.h"

#include <glm/gtc/constants.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <glbinding/gl/enum.h>
#include <glbinding/gl/bitfield.h>

#include <globjects/globjects.h>
#include <globjects/logging.h>
#include <globjects/DebugMessage.h>

#include <widgetzeug/make_unique.hpp>

#include <gloperate/base/RenderTargetType.h>

#include <gloperate/painter/TargetFramebufferCapability.h>
#include <gloperate/painter/ViewportCapability.h>
#include <gloperate/painter/PerspectiveProjectionCapability.h>
#include <gloperate/painter/CameraCapability.h>
#include <gloperate/painter/VirtualTimeCapability.h>

#include <globjects/Texture.h>
#include <globjects/AttachedTexture.h>

#include "OtherRenderer.h"
#include "RaycastingRenderer.h"

MetaballsExample::MetaballsExample(gloperate::ResourceManager & resourceManager)
:   Painter(resourceManager)
,   m_targetFramebufferCapability(addCapability(new gloperate::TargetFramebufferCapability()))
,   m_viewportCapability(addCapability(new gloperate::ViewportCapability()))
,   m_projectionCapability(addCapability(new gloperate::PerspectiveProjectionCapability(m_viewportCapability)))
,   m_cameraCapability(addCapability(new gloperate::CameraCapability()))
,	m_raycasting(true)
,	m_other(false)
{
	setupPropertyGroup();
}

MetaballsExample::~MetaballsExample() = default;

void MetaballsExample::setupProjection()
{
    //static const auto zNear = 0.3f, zFar = 15.f, fovy = 50.f;
}

void MetaballsExample::onInitialize()
{
    globjects::init();

#ifdef __APPLE__
    globjects::Shader::clearGlobalReplacements();
    globjects::Shader::globalReplace("#version 140", "#version 150");

    globjects::debug() << "Using global OS X shader replacement '#version 140' -> '#version 150'" << std::endl;
#endif
	gl::glClearColor(0.0, 0.0, 0.0, 1.0);

    m_texture = new globjects::Texture;
    m_texture->image2D(0, gl::GL_RGBA, m_viewportCapability->width(), m_viewportCapability->height(), 0, gl::GL_RGBA, gl::GL_UNSIGNED_BYTE, nullptr);

    m_fbo = new globjects::Framebuffer;
    m_fbo->attachTexture(gl::GL_COLOR_ATTACHMENT0, m_texture, 0);

    gl::glClearColor(0.0, 0.0, 0.0, 1.0);

    m_fbo->unbind();

	m_otherRenderer = std::make_unique<OtherRenderer>();
	m_rayRenderer = std::make_unique<RaycastingRenderer>();

	m_otherRenderer->initialize();
	m_rayRenderer->initialize();
}

void MetaballsExample::onPaint()
{
	m_fluidSimulator.update();

	if (m_viewportCapability->hasChanged())
	{
		m_texture->image2D(0, gl::GL_RGBA, m_viewportCapability->width(), m_viewportCapability->height(), 0, gl::GL_RGBA, gl::GL_UNSIGNED_BYTE, nullptr);

		m_viewportCapability->setChanged(false);
	}

	gl::glViewport(0, 0, m_viewportCapability->width(), m_viewportCapability->height());
	gl::glClear(gl::GL_COLOR_BUFFER_BIT);

	m_fbo->bind();
	gl::glClear(gl::GL_COLOR_BUFFER_BIT);

	std::array<int, 4> rect = { { 0, 0, m_viewportCapability->width(), m_viewportCapability->height() } };

	globjects::Framebuffer * targetFBO = m_targetFramebufferCapability->framebuffer() ? m_targetFramebufferCapability->framebuffer() : globjects::Framebuffer::defaultFBO();

	if (m_raycasting)
	{
		m_rayRenderer->draw(this, m_fluidSimulator.metaballs());

		targetFBO->bind(gl::GL_DRAW_FRAMEBUFFER);
		m_fbo->blit(gl::GL_COLOR_ATTACHMENT0, rect, targetFBO, gl::GL_BACK_LEFT, rect, gl::GL_COLOR_BUFFER_BIT, gl::GL_LINEAR);
	}
	if (m_other)
	{
		rect[0] += m_raycasting * static_cast<unsigned>(m_viewportCapability->width() / 2);

		m_otherRenderer->draw(this, m_fluidSimulator.metaballs());

		targetFBO->bind(gl::GL_DRAW_FRAMEBUFFER);
		m_fbo->blit(gl::GL_COLOR_ATTACHMENT0, rect, targetFBO, gl::GL_BACK_LEFT, rect, gl::GL_COLOR_BUFFER_BIT, gl::GL_LINEAR);
	}

	globjects::Framebuffer::unbind();
}

bool MetaballsExample::getRaycasting() const
{
	return m_raycasting;
}

void MetaballsExample::setRaycasting(bool value)
{
	m_raycasting = value;
	//m_other = !m_raycasting;
}

bool MetaballsExample::getOther() const
{
	return m_other;
}

void MetaballsExample::setOther(bool value)
{
	m_other = value;
	//m_raycasting = !m_other;
}

void MetaballsExample::setupPropertyGroup()
{
	addProperty<bool>("Raycasting", this,
		&MetaballsExample::getRaycasting, &MetaballsExample::setRaycasting);
	addProperty<bool>("Other", this,
		&MetaballsExample::getOther, &MetaballsExample::setOther);
}

const gloperate::AbstractTargetFramebufferCapability * MetaballsExample::targetFramebufferCapability() const
{
	return m_targetFramebufferCapability;
}

const gloperate::AbstractViewportCapability * MetaballsExample::viewportCapability() const
{
	return m_viewportCapability;
}

const gloperate::AbstractPerspectiveProjectionCapability * MetaballsExample::projectionCapability() const
{
	return m_projectionCapability;
}

const gloperate::AbstractCameraCapability * MetaballsExample::cameraCapability() const
{
	return m_cameraCapability;
<<<<<<< HEAD
>>>>>>> added environment map
=======
>>>>>>> fixed merge conflict
}<|endoftext|>


<commit_before>/*
 * SPDX-FileCopyrightText: 2010-2018 CSSlayer <wengxt@gmail.com>
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 */

#include <codecvt>
#include <cstring>
#if defined(__linux__) || defined(__GLIBC__)
#include <endian.h>
#else
#include <sys/endian.h>
#endif
#include <fcitx-utils/fs.h>
#include <fcitx-utils/log.h>
#include <fcitx-utils/stringutils.h>
#include <fcitx-utils/unixfd.h>
#include <fcntl.h>
#include <fstream>
#include <getopt.h>
#include <locale>
#include <unistd.h>

using namespace fcitx;

#define HEADER_SIZE 12
#define DELTBL_SIZE 10
#define BUFLEN 0x1000

#define DESC_START 0x130
#define DESC_LENGTH (0x338 - 0x130)

#define LDESC_LENGTH (0x540 - 0x338)
#define NEXT_LENGTH (0x1540 - 0x540)

#define PINYIN_SIZE 4

template <typename T>
void readOrAbort(const UnixFD &fd, T *value, int n,
                 const char *error = nullptr) {
    if (fs::safeRead(fd.fd(), value, n * sizeof(T)) !=
        static_cast<int>(n * sizeof(T))) {
        if (error) {
            FCITX_FATAL() << error;
        } else {
            exit(0);
        }
    }
}

template <typename T>
void readOrAbort(const UnixFD &fd, T *value, const char *error = nullptr) {
    return readOrAbort(fd, value, 1, error);
}

void readInt16(const UnixFD &fd, int16_t *value, const char *error = nullptr) {
    readOrAbort(fd, &value, error);
    *value = le16toh(*value);
}

std::string unicodeToUTF8(const char16_t *value, size_t size) {
    return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}
        .to_bytes(value, value + size);
}

std::string unicodeToUTF8(const char *value, size_t size) {
    FCITX_ASSERT(size % 2 == 0) << "Invalid size of string";
    const auto *ustr = reinterpret_cast<const uint16_t *>(value);
    std::u16string str;
    str.reserve(size / 2);
    for (size_t i = 0; i < size / 2; i++) {
        // either le or be will be 0
        if (ustr[i] == 0) {
            break;
        }
        str.push_back(le16toh(ustr[i]));
    }

    return unicodeToUTF8(str.data(), str.size());
}

static const char header_str[HEADER_SIZE] = {'\x40', '\x15', '\0',   '\0',
                                             '\x44', '\x43', '\x53', '\x01',
                                             '\x01', '\0',   '\0',   '\0'};
static const char pinyin_str[PINYIN_SIZE] = {'\x9d', '\x01', '\0', '\0'};
static const char deltbl_str[HEADER_SIZE] = {
    '\x45', '\0', '\x4c', '\0', '\x54', '\0', '\x42', '\0', '\x4c', '\0'};

static void usage() {
    puts("scel2org - Convert .scel file to libime compatible file (SEE NOTES "
         "BELOW)\n"
         "\n"
         "  usage: scel2org [OPTION] [scel file]\n"
         "\n"
         "  -o <file>  specify the output file, if not specified, the output "
         "will\n"
         "             be stdout.\n"
         "  -h         display this help.\n"
         "\n"
         "NOTES:\n"
         "   Always check the produced output for errors.\n");
    exit(1);
}

int main(int argc, char **argv) {
    int c;
    const char *outputFile = nullptr;
    bool printDel = false;

    while ((c = getopt(argc, argv, "o:hd")) != -1) {
        switch (c) {
        case 'o':
            outputFile = optarg;
            break;
        case 'd':
            printDel = true;
            break;
        case 'h':
        default:
            usage();
            break;
        }
    }

    std::ofstream fout;
    std::ostream *out;
    if (!outputFile || strcmp(outputFile, "-") == 0) {
        out = &std::cout;
    } else {
        fout.open(outputFile, std::ios::out | std::ios::binary);
        out = &fout;
    }

    if (optind >= argc) {
        usage();
        return 1;
    }

    UnixFD fd = UnixFD::own(open(argv[optind], O_RDONLY));
    if (!fd.isValid()) {
        FCITX_ERROR() << "Cannot open file: " << argv[optind];
        return 1;
    }

    char headerBuf[HEADER_SIZE];
    readOrAbort(fd, headerBuf, HEADER_SIZE, "Failed to read header");
    FCITX_ASSERT(memcmp(headerBuf, header_str, HEADER_SIZE) == 0)
        << " format error.";

    FCITX_ASSERT(lseek(fd.fd(), DESC_START, SEEK_SET) !=
                 static_cast<off_t>(-1));

    char descBuf[DESC_LENGTH];
    readOrAbort(fd, descBuf, DESC_LENGTH, "Failed to read description");
    std::cerr << "DESC:" << unicodeToUTF8(descBuf, DESC_LENGTH) << std::endl;

    char ldescBuf[LDESC_LENGTH];
    readOrAbort(fd, ldescBuf, LDESC_LENGTH, "Failed to read long description");
    std::cerr << "LDESC:" << unicodeToUTF8(ldescBuf, LDESC_LENGTH) << std::endl;

    char nextBuf[NEXT_LENGTH];
    readOrAbort(fd, nextBuf, NEXT_LENGTH, "Failed to read next description");
    std::cerr << "NEXT:" << unicodeToUTF8(nextBuf, NEXT_LENGTH) << std::endl;

    char pyBuf[PINYIN_SIZE];
    readOrAbort(fd, pyBuf, PINYIN_SIZE, "Failed to read py");
    FCITX_ASSERT(memcmp(pyBuf, pinyin_str, PINYIN_SIZE) == 0);

    std::vector<std::string> pys;

    while (true) {
        int16_t index;
        int16_t count;
        readInt16(fd, &index, "failed to read index");
        readInt16(fd, &count, "failed to read pinyin count");

        std::vector<char> buf;
        buf.resize(count);

        readOrAbort(fd, buf.data(), count, "Failed to read py");

        std::string py = unicodeToUTF8(buf.data(), buf.size());

        // Replace ue with ve
        if (py == "lue" || py == "nue") {
            py[py.size() - 2] = 'v';
        }
        pys.push_back(py);

        if (py == "zuo") {
            break;
        }
    }

    while (true) {
        int16_t symcount;
        int16_t count;
        int16_t wordcount;
        readInt16(fd, &symcount);

        if (le16toh(symcount) == 0x44) {
            break;
        }

        readInt16(fd, &count, "Failed to read count");

        wordcount = count / 2;
        std::vector<int16_t> pyindex;
        pyindex.resize(wordcount);

        readOrAbort(fd, pyindex.data(), wordcount, "Failed to read pyindex");

        int s;

        for (s = 0; s < symcount; s++) {
            std::vector<char> buf;
            readInt16(fd, &count, "Failed to read count");
            buf.resize(count);
            readOrAbort(fd, buf.data(), count, "Failed to read text");
            std::string bufout = unicodeToUTF8(buf.data(), buf.size());

            *out << bufout << "\t";
            *out << pys[pyindex[0]];
            for (auto i = 1; i < wordcount; i++) {
                *out << '\'' << pys[pyindex[i]];
            }

            *out << "\t0" << std::endl;

            readInt16(fd, &count, "failed to read count");
            buf.resize(count);
            readOrAbort(fd, buf.data(), buf.size(), "failed to read buf");
        }
    }

    char delTblBuf[DELTBL_SIZE];
    if (fs::safeRead(fd.fd(), delTblBuf, DELTBL_SIZE) != DELTBL_SIZE ||
        memcmp(delTblBuf, deltbl_str, DELTBL_SIZE) != 0) {
        return 0;
    }

    if (!printDel) {
        return 0;
    }

    int16_t delTblCount;
    readInt16(fd, &delTblCount);
    for (int i = 0; i < delTblCount; i++) {
        int16_t count;
        readInt16(fd, &count);
        count *= 2;
        std::vector<char> buf;
        buf.resize(count);
        readOrAbort(fd, buf.data(), count, "Failed to read text");
        std::string bufout = unicodeToUTF8(buf.data(), buf.size());
        std::cerr << "DEL:" << bufout << std::endl;
    }

    return 0;
}
<commit_msg>Fix reading value.<commit_after>/*
 * SPDX-FileCopyrightText: 2010-2018 CSSlayer <wengxt@gmail.com>
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 */

#include <codecvt>
#include <cstring>
#if defined(__linux__) || defined(__GLIBC__)
#include <endian.h>
#else
#include <sys/endian.h>
#endif
#include <fcitx-utils/fs.h>
#include <fcitx-utils/log.h>
#include <fcitx-utils/stringutils.h>
#include <fcitx-utils/unixfd.h>
#include <fcntl.h>
#include <fstream>
#include <getopt.h>
#include <locale>
#include <unistd.h>

using namespace fcitx;

#define HEADER_SIZE 12
#define DELTBL_SIZE 10
#define BUFLEN 0x1000

#define DESC_START 0x130
#define DESC_LENGTH (0x338 - 0x130)

#define LDESC_LENGTH (0x540 - 0x338)
#define NEXT_LENGTH (0x1540 - 0x540)

#define PINYIN_SIZE 4

template <typename T>
void readOrAbort(const UnixFD &fd, T *value, int n,
                 const char *error = nullptr) {
    if (fs::safeRead(fd.fd(), value, n * sizeof(T)) !=
        static_cast<int>(n * sizeof(T))) {
        if (error) {
            FCITX_FATAL() << error;
        } else {
            exit(0);
        }
    }
}

template <typename T>
void readOrAbort(const UnixFD &fd, T *value, const char *error = nullptr) {
    return readOrAbort(fd, value, 1, error);
}

void readInt16(const UnixFD &fd, int16_t *value, const char *error = nullptr) {
    readOrAbort(fd, value, error);
    *value = le16toh(*value);
}

std::string unicodeToUTF8(const char16_t *value, size_t size) {
    return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}
        .to_bytes(value, value + size);
}

std::string unicodeToUTF8(const char *value, size_t size) {
    FCITX_ASSERT(size % 2 == 0) << "Invalid size of string";
    const auto *ustr = reinterpret_cast<const uint16_t *>(value);
    std::u16string str;
    str.reserve(size / 2);
    for (size_t i = 0; i < size / 2; i++) {
        // either le or be will be 0
        if (ustr[i] == 0) {
            break;
        }
        str.push_back(le16toh(ustr[i]));
    }

    return unicodeToUTF8(str.data(), str.size());
}

static const char header_str[HEADER_SIZE] = {'\x40', '\x15', '\0',   '\0',
                                             '\x44', '\x43', '\x53', '\x01',
                                             '\x01', '\0',   '\0',   '\0'};
static const char pinyin_str[PINYIN_SIZE] = {'\x9d', '\x01', '\0', '\0'};
static const char deltbl_str[HEADER_SIZE] = {
    '\x45', '\0', '\x4c', '\0', '\x54', '\0', '\x42', '\0', '\x4c', '\0'};

static void usage() {
    puts("scel2org - Convert .scel file to libime compatible file (SEE NOTES "
         "BELOW)\n"
         "\n"
         "  usage: scel2org [OPTION] [scel file]\n"
         "\n"
         "  -o <file>  specify the output file, if not specified, the output "
         "will\n"
         "             be stdout.\n"
         "  -h         display this help.\n"
         "\n"
         "NOTES:\n"
         "   Always check the produced output for errors.\n");
    exit(1);
}

int main(int argc, char **argv) {
    int c;
    const char *outputFile = nullptr;
    bool printDel = false;

    while ((c = getopt(argc, argv, "o:hd")) != -1) {
        switch (c) {
        case 'o':
            outputFile = optarg;
            break;
        case 'd':
            printDel = true;
            break;
        case 'h':
        default:
            usage();
            break;
        }
    }

    std::ofstream fout;
    std::ostream *out;
    if (!outputFile || strcmp(outputFile, "-") == 0) {
        out = &std::cout;
    } else {
        fout.open(outputFile, std::ios::out | std::ios::binary);
        out = &fout;
    }

    if (optind >= argc) {
        usage();
        return 1;
    }

    UnixFD fd = UnixFD::own(open(argv[optind], O_RDONLY));
    if (!fd.isValid()) {
        FCITX_ERROR() << "Cannot open file: " << argv[optind];
        return 1;
    }

    char headerBuf[HEADER_SIZE];
    readOrAbort(fd, headerBuf, HEADER_SIZE, "Failed to read header");
    FCITX_ASSERT(memcmp(headerBuf, header_str, HEADER_SIZE) == 0)
        << " format error.";

    FCITX_ASSERT(lseek(fd.fd(), DESC_START, SEEK_SET) !=
                 static_cast<off_t>(-1));

    char descBuf[DESC_LENGTH];
    readOrAbort(fd, descBuf, DESC_LENGTH, "Failed to read description");
    std::cerr << "DESC:" << unicodeToUTF8(descBuf, DESC_LENGTH) << std::endl;

    char ldescBuf[LDESC_LENGTH];
    readOrAbort(fd, ldescBuf, LDESC_LENGTH, "Failed to read long description");
    std::cerr << "LDESC:" << unicodeToUTF8(ldescBuf, LDESC_LENGTH) << std::endl;

    char nextBuf[NEXT_LENGTH];
    readOrAbort(fd, nextBuf, NEXT_LENGTH, "Failed to read next description");
    std::cerr << "NEXT:" << unicodeToUTF8(nextBuf, NEXT_LENGTH) << std::endl;

    char pyBuf[PINYIN_SIZE];
    readOrAbort(fd, pyBuf, PINYIN_SIZE, "Failed to read py");
    FCITX_ASSERT(memcmp(pyBuf, pinyin_str, PINYIN_SIZE) == 0);

    std::vector<std::string> pys;

    while (true) {
        int16_t index;
        int16_t count;
        readInt16(fd, &index, "failed to read index");
        readInt16(fd, &count, "failed to read pinyin count");

        std::vector<char> buf;
        buf.resize(count);

        readOrAbort(fd, buf.data(), count, "Failed to read py");

        std::string py = unicodeToUTF8(buf.data(), buf.size());

        // Replace ue with ve
        if (py == "lue" || py == "nue") {
            py[py.size() - 2] = 'v';
        }
        pys.push_back(py);

        if (py == "zuo") {
            break;
        }
    }

    while (true) {
        int16_t symcount;
        int16_t count;
        int16_t wordcount;
        readInt16(fd, &symcount);

        if (le16toh(symcount) == 0x44) {
            break;
        }

        readInt16(fd, &count, "Failed to read count");

        wordcount = count / 2;
        std::vector<int16_t> pyindex;
        pyindex.resize(wordcount);

        readOrAbort(fd, pyindex.data(), wordcount, "Failed to read pyindex");

        int s;

        for (s = 0; s < symcount; s++) {
            std::vector<char> buf;
            readInt16(fd, &count, "Failed to read count");
            buf.resize(count);
            readOrAbort(fd, buf.data(), count, "Failed to read text");
            std::string bufout = unicodeToUTF8(buf.data(), buf.size());

            *out << bufout << "\t";
            *out << pys[pyindex[0]];
            for (auto i = 1; i < wordcount; i++) {
                *out << '\'' << pys[pyindex[i]];
            }

            *out << "\t0" << std::endl;

            readInt16(fd, &count, "failed to read count");
            buf.resize(count);
            readOrAbort(fd, buf.data(), buf.size(), "failed to read buf");
        }
    }

    char delTblBuf[DELTBL_SIZE];
    if (fs::safeRead(fd.fd(), delTblBuf, DELTBL_SIZE) != DELTBL_SIZE ||
        memcmp(delTblBuf, deltbl_str, DELTBL_SIZE) != 0) {
        return 0;
    }

    if (!printDel) {
        return 0;
    }

    int16_t delTblCount;
    readInt16(fd, &delTblCount);
    for (int i = 0; i < delTblCount; i++) {
        int16_t count;
        readInt16(fd, &count);
        count *= 2;
        std::vector<char> buf;
        buf.resize(count);
        readOrAbort(fd, buf.data(), count, "Failed to read text");
        std::string bufout = unicodeToUTF8(buf.data(), buf.size());
        std::cerr << "DEL:" << bufout << std::endl;
    }

    return 0;
}
<|endoftext|>


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

#include "Basics/MutexLocker.h"
#include "Basics/ConditionLocker.h"

#include <chrono>
#include <thread>

#include <velocypack/Exception.h>
#include <velocypack/Parser.h>
#include <velocypack/velocypack-aliases.h>

#include "AgencyCallback.h"

using namespace arangodb;

AgencyCallback::AgencyCallback(AgencyComm& agency,
                               std::string const& key,
                               std::function<bool(VPackSlice const&)> const& cb,
                               bool needsValue,
                               bool needsInitialValue)
  : key(key),
    _useCv(false),
    _agency(agency),
    _cb(cb),
    _needsValue(needsValue) {
  if (_needsValue && needsInitialValue) {
    refetchAndUpdate();
  }
}

void AgencyCallback::refetchAndUpdate() {
  if (!_needsValue) {
    // no need to pass any value to the callback
    executeEmpty();
    return;
  }

  AgencyCommResult result = _agency.getValues(key, true);

  if (!result.successful()) {
    return;
  }

  if (!result.parse("", false)) {
    LOG(ERR) << "Cannot parse body " << result.body();
    return;
  }

  // mop: we need to find out if it is a directory :S
  // because we lost this information while parsing
  std::shared_ptr<VPackBuilder> bodyBuilder =
      VPackParser::fromJson(result.body().c_str());

  VPackSlice slice = bodyBuilder->slice();
  if (!slice.isObject() || !slice.hasKey("node")) {
    LOG(ERR) << "Invalid structure " << result.body();
    return;
  }

  VPackSlice node = slice.get("node");
  if (!slice.isObject()) {
    LOG(ERR) << "Node is not an object";
    return;
  }

  bool isDir = node.hasKey("dir");

  std::shared_ptr<VPackBuilder> newData = std::make_shared<VPackBuilder>();
  if (isDir) {
    VPackObjectBuilder builder(newData.get());
    for (auto& it: result._values) {
      newData->add(it.first, it.second._vpack->slice());
    }
  } else if (result._values.size() == 0) {
    newData->add(VPackSlice::noneSlice());
  } else {
    newData->add(result._values.begin()->second._vpack->slice());
  }
  checkValue(newData);
}

void AgencyCallback::checkValue(std::shared_ptr<VPackBuilder> newData) {
  if (!_lastData || !_lastData->slice().equals(newData->slice())) {
    LOG(DEBUG) << "Got new value " << newData->slice().typeName() << " " << newData->toJson();
    if (execute(newData)) {
      _lastData = newData;
    } else {
      LOG(DEBUG) << "Callback was not successful for " << newData->toJson();
    }
  }
}

bool AgencyCallback::executeEmpty() {
  LOG(DEBUG) << "Executing (empty)";
  bool result;
  {
    MUTEX_LOCKER(locker, _lock);
    result = _cb(VPackSlice::noneSlice());
  }

  if (_useCv) {
    CONDITION_LOCKER(locker, _cv);
    _cv.signal();
  }
  return result;
}

bool AgencyCallback::execute(std::shared_ptr<VPackBuilder> newData) {
  LOG(DEBUG) << "Executing";
  bool result;
  {
    MUTEX_LOCKER(locker, _lock);
    result = _cb(newData->slice());
  }

  if (_useCv) {
    CONDITION_LOCKER(locker, _cv);
    _cv.signal();
  }
  return result;
}

void AgencyCallback::waitWithFailover(double timeout) {
  VPackSlice compareSlice;
  if (_lastData) {
    compareSlice = _lastData->slice();
  } else {
    compareSlice = VPackSlice::noneSlice();
  }

  std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int>(timeout * 1000)));

  if (!_lastData || _lastData->slice().equals(compareSlice)) {
    LOG(DEBUG) << "Waiting done and nothing happended. Refetching to be sure";
    // mop: watches have not triggered during our sleep...recheck to be sure
    refetchAndUpdate();
  }
}

void AgencyCallback::waitForExecution(double maxTimeout) {
  VPackSlice compareSlice;
  if (_lastData) {
    compareSlice = _lastData->slice();
  } else {
    compareSlice = VPackSlice::noneSlice();
  }

  _useCv = true;
  CONDITION_LOCKER(locker, _cv);
  locker.wait(static_cast<uint64_t>(maxTimeout * 1000000.0));
  _useCv = false;

  if (!_lastData || _lastData->slice().equals(compareSlice)) {
    LOG(DEBUG) << "Waiting done and nothing happended. Refetching to be sure";
    // mop: watches have not triggered during our sleep...recheck to be sure
    refetchAndUpdate();
  }
}
<commit_msg>Fix use after free<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Andreas Streichardt
////////////////////////////////////////////////////////////////////////////////

#include "Basics/MutexLocker.h"
#include "Basics/ConditionLocker.h"

#include <chrono>
#include <thread>

#include <velocypack/Exception.h>
#include <velocypack/Parser.h>
#include <velocypack/velocypack-aliases.h>

#include "AgencyCallback.h"

using namespace arangodb;

AgencyCallback::AgencyCallback(AgencyComm& agency,
                               std::string const& key,
                               std::function<bool(VPackSlice const&)> const& cb,
                               bool needsValue,
                               bool needsInitialValue)
  : key(key),
    _useCv(false),
    _agency(agency),
    _cb(cb),
    _needsValue(needsValue) {
  if (_needsValue && needsInitialValue) {
    refetchAndUpdate();
  }
}

void AgencyCallback::refetchAndUpdate() {
  if (!_needsValue) {
    // no need to pass any value to the callback
    executeEmpty();
    return;
  }

  AgencyCommResult result = _agency.getValues(key, true);

  if (!result.successful()) {
    return;
  }

  if (!result.parse("", false)) {
    LOG(ERR) << "Cannot parse body " << result.body();
    return;
  }

  // mop: we need to find out if it is a directory :S
  // because we lost this information while parsing
  std::shared_ptr<VPackBuilder> bodyBuilder =
      VPackParser::fromJson(result.body().c_str());

  VPackSlice slice = bodyBuilder->slice();
  if (!slice.isObject() || !slice.hasKey("node")) {
    LOG(ERR) << "Invalid structure " << result.body();
    return;
  }

  VPackSlice node = slice.get("node");
  if (!slice.isObject()) {
    LOG(ERR) << "Node is not an object";
    return;
  }

  bool isDir = node.hasKey("dir");

  std::shared_ptr<VPackBuilder> newData = std::make_shared<VPackBuilder>();
  if (isDir) {
    VPackObjectBuilder builder(newData.get());
    for (auto& it: result._values) {
      newData->add(it.first, it.second._vpack->slice());
    }
  } else if (result._values.size() == 0) {
    newData->add(VPackSlice::noneSlice());
  } else {
    newData->add(result._values.begin()->second._vpack->slice());
  }
  checkValue(newData);
}

void AgencyCallback::checkValue(std::shared_ptr<VPackBuilder> newData) {
  if (!_lastData || !_lastData->slice().equals(newData->slice())) {
    LOG(DEBUG) << "Got new value " << newData->slice().typeName() << " " << newData->toJson();
    if (execute(newData)) {
      _lastData = newData;
    } else {
      LOG(DEBUG) << "Callback was not successful for " << newData->toJson();
    }
  }
}

bool AgencyCallback::executeEmpty() {
  LOG(DEBUG) << "Executing (empty)";
  bool result;
  {
    MUTEX_LOCKER(locker, _lock);
    result = _cb(VPackSlice::noneSlice());
  }

  if (_useCv) {
    CONDITION_LOCKER(locker, _cv);
    _cv.signal();
  }
  return result;
}

bool AgencyCallback::execute(std::shared_ptr<VPackBuilder> newData) {
  LOG(DEBUG) << "Executing";
  bool result;
  {
    MUTEX_LOCKER(locker, _lock);
    result = _cb(newData->slice());
  }

  if (_useCv) {
    CONDITION_LOCKER(locker, _cv);
    _cv.signal();
  }
  return result;
}

void AgencyCallback::waitWithFailover(double timeout) {
  VPackSlice compareSlice;
  if (_lastData) {
    compareSlice = _lastData->slice();
  } else {
    compareSlice = VPackSlice::noneSlice();
  }

  std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int>(timeout * 1000)));

  if (!_lastData || _lastData->slice().equals(compareSlice)) {
    LOG(DEBUG) << "Waiting done and nothing happended. Refetching to be sure";
    // mop: watches have not triggered during our sleep...recheck to be sure
    refetchAndUpdate();
  }
}

void AgencyCallback::waitForExecution(double maxTimeout) {
  auto compareBuilder = std::make_shared<VPackBuilder>();
  if (_lastData) {
    compareBuilder = _lastData;
  }

  _useCv = true;
  CONDITION_LOCKER(locker, _cv);
  locker.wait(static_cast<uint64_t>(maxTimeout * 1000000.0));
  _useCv = false;

  if (!_lastData || _lastData->slice().equals(compareBuilder->slice())) {
    LOG(DEBUG) << "Waiting done and nothing happended. Refetching to be sure";
    // mop: watches have not triggered during our sleep...recheck to be sure
    refetchAndUpdate();
  }
}
<|endoftext|>