<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: animationaudionode.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 15:28:14 $
 *
 *  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 INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX
#define INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX

#include "basecontainernode.hxx"
#include "soundplayer.hxx"
#include "com/sun/star/animations/XAnimationNode.hpp"
#include "com/sun/star/animations/XAudio.hpp"

namespace slideshow {
namespace internal {

/** Audio node.

    This animation node contains an audio effect. Duration and
    start/stop behaviour is affected by the referenced audio
    file.
*/
class AnimationAudioNode : public BaseNode, public AnimationEventHandler
{
public:
    AnimationAudioNode(
        ::com::sun::star::uno::Reference<
        ::com::sun::star::animations::XAnimationNode> const& xNode,
        ::boost::shared_ptr<BaseContainerNode> const& pParent,
        NodeContext const& rContext );

protected:
    virtual void dispose();

private:
    virtual void activate_st();
    virtual void deactivate_st( NodeState eDestState );
    virtual bool hasPendingAnimation() const;

    /// overriden, because we need to deal with STOPAUDIO commands
    virtual bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode );

private:
    ::com::sun::star::uno::Reference<
        ::com::sun::star::animations::XAudio >  mxAudioNode;
    ::rtl::OUString                             maSoundURL;
    mutable SoundPlayerSharedPtr                mpPlayer;

    void createPlayer() const;
    void resetPlayer() const;
};

} // namespace internal
} // namespace slideshow

#endif /* INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX */
<commit_msg>INTEGRATION: CWS changefileheader (1.8.74); FILE MERGED 2008/03/31 14:00:17 rt 1.8.74.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: animationaudionode.hxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX
#define INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX

#include "basecontainernode.hxx"
#include "soundplayer.hxx"
#include "com/sun/star/animations/XAnimationNode.hpp"
#include "com/sun/star/animations/XAudio.hpp"

namespace slideshow {
namespace internal {

/** Audio node.

    This animation node contains an audio effect. Duration and
    start/stop behaviour is affected by the referenced audio
    file.
*/
class AnimationAudioNode : public BaseNode, public AnimationEventHandler
{
public:
    AnimationAudioNode(
        ::com::sun::star::uno::Reference<
        ::com::sun::star::animations::XAnimationNode> const& xNode,
        ::boost::shared_ptr<BaseContainerNode> const& pParent,
        NodeContext const& rContext );

protected:
    virtual void dispose();

private:
    virtual void activate_st();
    virtual void deactivate_st( NodeState eDestState );
    virtual bool hasPendingAnimation() const;

    /// overriden, because we need to deal with STOPAUDIO commands
    virtual bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode );

private:
    ::com::sun::star::uno::Reference<
        ::com::sun::star::animations::XAudio >  mxAudioNode;
    ::rtl::OUString                             maSoundURL;
    mutable SoundPlayerSharedPtr                mpPlayer;

    void createPlayer() const;
    void resetPlayer() const;
};

} // namespace internal
} // namespace slideshow

#endif /* INCLUDED_SLIDESHOW_ANIMATIONAUDIONODE_HXX */
<|endoftext|>


<commit_before>#include <utility>

#include "level.h"
#include "math.h"
#include "logger.h"

Level::Level()
  : valid_(false),
    width_(0),
    height_(0),
    player_(),
    tiles_background_(),
    tiles_foreground_(),
    aabbs_(),
    platforms_(),
    objects_(),
    moving_platforms_(),
    vertical_platform_(),
    horizontal_platform_(),
    earth_(),
    moon_(),
    volcano_()
{
}

Level::Level(int width,
             int height,
             std::vector<Item::Id> tiles_background,
             std::vector<Item::Id> tiles_foreground,
             std::vector<geometry::Rectangle> aabbs,
             std::vector<geometry::Position> platforms)
  : valid_(true),
    width_(width),
    height_(height),
    player_(),
    tiles_background_(std::move(tiles_background)),
    tiles_foreground_(std::move(tiles_foreground)),
    aabbs_(std::move(aabbs)),
    platforms_(std::move(platforms)),
    objects_(),
    moving_platforms_(),
    vertical_platform_(),
    horizontal_platform_(),
    earth_(),
    moon_(),
    volcano_()
{
  player_.position = geometry::Position(32, 48);
  player_.velocity = Vector<int>(0, 0);
  player_.direction = Player::Direction::right;
}

Item::Id Level::get_tile_background(int tile_x, int tile_y) const
{
  return get_tile(tile_x, tile_y, tiles_background_);
}

Item::Id Level::get_tile_foreground(int tile_x, int tile_y) const
{
  return get_tile(tile_x, tile_y, tiles_foreground_);
}

Item::Id Level::get_tile(int tile_x, int tile_y, const std::vector<Item::Id>& items) const
{
  if (tile_x >= 0 && tile_x < width_ && tile_y >= 0 && tile_y < height_)
  {
    return items[(tile_y * width_) + tile_x];
  }
  else
  {
    return Item::invalid;
  }
}

void Level::update(unsigned game_tick)
{
  // Clear all objects and moving platforms
  objects_.clear();
  moving_platforms_.clear();

  // Update vertical platform
  if (vertical_platform_.down)
  {
    vertical_platform_.position_y += 2;
    if (vertical_platform_.position_y == 22 * 16)
    {
      vertical_platform_.down = false;
    }
  }
  else
  {
    vertical_platform_.position_y -= 2;
    if (vertical_platform_.position_y == (7 * 16) + 4)
    {
      vertical_platform_.down = true;
    }
  }

  // Update horizontal platform
  // FIXME: Speed isn't exactly correct. Crystal Caves is a bit slower
  // 1.5 per tick? e.g. +3 px every other tick?
  if (horizontal_platform_.right)
  {
    horizontal_platform_.position_x += 2;
    if (horizontal_platform_.position_x == 11 * 16)
    {
      horizontal_platform_.right = false;
    }
  }
  else
  {
    horizontal_platform_.position_x -= 2;
    if (horizontal_platform_.position_x == 7 * 16)
    {
      horizontal_platform_.right = true;
    }
  }

  // Update earth
  if (earth_.right)
  {
    earth_.position_x += 1;
    if ((earth_.position_x / 2) + 16 == width_ * 16)
    {
      earth_.right = false;
    }
  }
  else
  {
    earth_.position_x -= 1;
    if (earth_.position_x == 32)
    {
      earth_.right = true;
    }
  }

  // Update moon
  if (moon_.right)
  {
    moon_.position_x += earth_.right ? 2 : 1;
    if (moon_.position_x > earth_.position_x + 72 || (moon_.position_x / 2) + 16 == width_ * 16)
    {
      moon_.right = false;
    }
  }
  else
  {
    moon_.position_x -= !earth_.right ? 2 : 1;
    if (moon_.position_x < earth_.position_x - 64 || moon_.position_x == 32)
    {
      moon_.right = true;
    }
  }

  // Update volcano
  if (volcano_.active && game_tick - volcano_.tick_start >= 81u)
  {
    volcano_.active = false;
    volcano_.tick_start = game_tick;
  }
  else if (!volcano_.active && game_tick - volcano_.tick_start >= 220u)
  {
    volcano_.active = true;
    volcano_.tick_start = game_tick;
  }

  // Add objects
  if (moon_.right)
  {
    // Moon is behind earth, render moon first
    objects_.emplace_back(geometry::Position(moon_.position_x / 2, 0), geometry::Size(16, 16), 634);
    objects_.emplace_back(geometry::Position(earth_.position_x / 2, 0), geometry::Size(16, 16), 632);
  }
  else
  {
    // Moon is in front of earth, render earth first
    objects_.emplace_back(geometry::Position(earth_.position_x / 2, 0), geometry::Size(16, 16), 632);
    objects_.emplace_back(geometry::Position(moon_.position_x / 2, 0), geometry::Size(16, 16), 633);
  }

  if (volcano_.active)
  {
    const auto volcano_sprite_index = ((game_tick - volcano_.tick_start) / 3) % 4;
    objects_.emplace_back(geometry::Position(29 * 16, 2 * 16),
                          geometry::Size(16, 16),
                          752 + volcano_sprite_index);
    objects_.emplace_back(geometry::Position(30 * 16, 2 * 16),
                          geometry::Size(16, 16),
                          748 + volcano_sprite_index);
  }

  const auto platform_sprite_index = game_tick % 4;
  objects_.emplace_back(geometry::Position(38 * 16, vertical_platform_.position_y),
                        geometry::Size(16, 16),
                        616 + platform_sprite_index);
  objects_.emplace_back(geometry::Position(horizontal_platform_.position_x, 8 * 16),
                        geometry::Size(16, 16),
                        612 + platform_sprite_index);
}
<commit_msg>Moving platforms moves the player, but still no collision detection<commit_after>#include <utility>

#include "level.h"
#include "math.h"
#include "logger.h"

Level::Level()
  : valid_(false),
    width_(0),
    height_(0),
    player_(),
    tiles_background_(),
    tiles_foreground_(),
    aabbs_(),
    platforms_(),
    objects_(),
    moving_platforms_(),
    vertical_platform_(),
    horizontal_platform_(),
    earth_(),
    moon_(),
    volcano_()
{
}

Level::Level(int width,
             int height,
             std::vector<Item::Id> tiles_background,
             std::vector<Item::Id> tiles_foreground,
             std::vector<geometry::Rectangle> aabbs,
             std::vector<geometry::Position> platforms)
  : valid_(true),
    width_(width),
    height_(height),
    player_(),
    tiles_background_(std::move(tiles_background)),
    tiles_foreground_(std::move(tiles_foreground)),
    aabbs_(std::move(aabbs)),
    platforms_(std::move(platforms)),
    objects_(),
    moving_platforms_(),
    vertical_platform_(),
    horizontal_platform_(),
    earth_(),
    moon_(),
    volcano_()
{
  player_.position = geometry::Position(32, 48);
  player_.velocity = Vector<int>(0, 0);
  player_.direction = Player::Direction::right;
}

Item::Id Level::get_tile_background(int tile_x, int tile_y) const
{
  return get_tile(tile_x, tile_y, tiles_background_);
}

Item::Id Level::get_tile_foreground(int tile_x, int tile_y) const
{
  return get_tile(tile_x, tile_y, tiles_foreground_);
}

Item::Id Level::get_tile(int tile_x, int tile_y, const std::vector<Item::Id>& items) const
{
  if (tile_x >= 0 && tile_x < width_ && tile_y >= 0 && tile_y < height_)
  {
    return items[(tile_y * width_) + tile_x];
  }
  else
  {
    return Item::invalid;
  }
}

void Level::update(unsigned game_tick)
{
  // Clear all objects and moving platforms
  objects_.clear();
  moving_platforms_.clear();

  // Update vertical platform
  const auto player_on_vertical_platform = (player_.position.y() + player_.size.y() == vertical_platform_.position_y) &&
                                           (player_.position.x() < (38 * 16) + 16) &&
                                           (player_.position.x() + player_.size.x() > 38 * 16);

  if (player_on_vertical_platform)
  {
    player_.position += vertical_platform_.down ? geometry::Position(0, 2) : geometry::Position(0, -2);
  }

  vertical_platform_.position_y += vertical_platform_.down ? 2 : -2;
  if (vertical_platform_.position_y == (vertical_platform_.down ? (22 * 16) : ((7 * 16) + 4)))
  {
    vertical_platform_.down = !vertical_platform_.down;
  }

  // Update horizontal platform
  // FIXME: Speed isn't exactly correct. Crystal Caves is a bit slower
  // 1.5 per tick? e.g. +3 px every other tick?
  const auto player_on_horizontal_platform = (player_.position.y() + player_.size.y() == 8 * 16) &&
                                             (player_.position.x() < horizontal_platform_.position_x + 16) &&
                                             (player_.position.x() + player_.size.x() > horizontal_platform_.position_x);
  if (player_on_horizontal_platform)
  {
    player_.position += horizontal_platform_.right ? geometry::Position(2, 0) : geometry::Position(-2, 0);
  }

  horizontal_platform_.position_x += horizontal_platform_.right ? 2 : -2;
  if (horizontal_platform_.position_x == (horizontal_platform_.right ? (11 * 16) : (7 * 16)))
  {
    horizontal_platform_.right = !horizontal_platform_.right;
  }

  // Update earth
  if (earth_.right)
  {
    earth_.position_x += 1;
    if ((earth_.position_x / 2) + 16 == width_ * 16)
    {
      earth_.right = false;
    }
  }
  else
  {
    earth_.position_x -= 1;
    if (earth_.position_x == 32)
    {
      earth_.right = true;
    }
  }

  // Update moon
  if (moon_.right)
  {
    moon_.position_x += earth_.right ? 2 : 1;
    if (moon_.position_x > earth_.position_x + 72 || (moon_.position_x / 2) + 16 == width_ * 16)
    {
      moon_.right = false;
    }
  }
  else
  {
    moon_.position_x -= !earth_.right ? 2 : 1;
    if (moon_.position_x < earth_.position_x - 64 || moon_.position_x == 32)
    {
      moon_.right = true;
    }
  }

  // Update volcano
  if (volcano_.active && game_tick - volcano_.tick_start >= 81u)
  {
    volcano_.active = false;
    volcano_.tick_start = game_tick;
  }
  else if (!volcano_.active && game_tick - volcano_.tick_start >= 220u)
  {
    volcano_.active = true;
    volcano_.tick_start = game_tick;
  }

  // Add objects
  if (moon_.right)
  {
    // Moon is behind earth, render moon first
    objects_.emplace_back(geometry::Position(moon_.position_x / 2, 0), geometry::Size(16, 16), 634);
    objects_.emplace_back(geometry::Position(earth_.position_x / 2, 0), geometry::Size(16, 16), 632);
  }
  else
  {
    // Moon is in front of earth, render earth first
    objects_.emplace_back(geometry::Position(earth_.position_x / 2, 0), geometry::Size(16, 16), 632);
    objects_.emplace_back(geometry::Position(moon_.position_x / 2, 0), geometry::Size(16, 16), 633);
  }

  if (volcano_.active)
  {
    const auto volcano_sprite_index = ((game_tick - volcano_.tick_start) / 3) % 4;
    objects_.emplace_back(geometry::Position(29 * 16, 2 * 16),
                          geometry::Size(16, 16),
                          752 + volcano_sprite_index);
    objects_.emplace_back(geometry::Position(30 * 16, 2 * 16),
                          geometry::Size(16, 16),
                          748 + volcano_sprite_index);
  }

  const auto platform_sprite_index = game_tick % 4;
  objects_.emplace_back(geometry::Position(38 * 16, vertical_platform_.position_y),
                        geometry::Size(16, 16),
                        616 + platform_sprite_index);
  objects_.emplace_back(geometry::Position(horizontal_platform_.position_x, 8 * 16),
                        geometry::Size(16, 16),
                        612 + platform_sprite_index);
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialogopen.h"
#include "dialognew.h"

#include <QFileSystemModel>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    folderHistory(new QStack<QString>),
    folderForwardHistory(new QStack<QString>)
{
    // Setup the UI
    ui->setupUi(this);

    // Create file system models
    model = new QFileSystemModel(this);
    model->setRootPath(QDir::homePath());
    modelDirs = new QFileSystemModel(this);
    modelDirs->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);

    // Set models in views
    ui->treeViewExplorer->setModel(model);
    ui->treeViewExplorer->setRootIndex(model->index(QDir::homePath()));
    ui->treeViewFiles->setModel(modelDirs);
    ui->treeViewFiles->hideColumn(3);
    ui->treeViewFiles->hideColumn(2);
    ui->treeViewFiles->hideColumn(1);

    // Add to stack
    folderHistory->append(QDir::homePath());

    // Show path in status bar
    this->setPath();
}

MainWindow::~MainWindow()
{
    delete ui;
    delete folderHistory;
    delete folderForwardHistory;
    delete model;
    delete modelDirs;
}

void MainWindow::on_treeViewExplorer_doubleClicked(const QModelIndex &index)
{
    // Get directory
    QString dir(model->filePath(index));

    // clear forward if it doesn't contain dir
    // else pop from ForwardHistory
    if (!folderForwardHistory->contains(dir)) folderForwardHistory->clear();
    else folderForwardHistory->pop();

    // Add to stack
    folderHistory->append(dir);

    // Set root index
    ui->treeViewExplorer->setRootIndex(model->index(dir));

    // Show path in status bar
    this->setPath();
}

void MainWindow::on_treeViewFiles_clicked(const QModelIndex &index)
{
    this->on_treeViewExplorer_doubleClicked(index);
}

void MainWindow::on_buttonBack_clicked()
{
    // Track dir
    QString dir;

    // More than only the home item
    if(folderHistory->size() > 0)
    {
        // Get the first item of the stack
        dir = folderHistory->pop();

        // Add to folderForwardHistory
        folderForwardHistory->append(dir);

        // Is it the current directory?
        if(folderHistory->size() > 0 && ui->treeViewExplorer->rootIndex() == model->index(dir)) {
            // Pop another
            dir = folderHistory->last();
        }

        // Set root index
        ui->treeViewExplorer->setRootIndex(model->index(dir));
    }

    // History empty?
    if(folderHistory->size() == 0)
    {
        // Append the last dir as it must be the starting point
        folderHistory->append(dir);
    }

    // Show path in status bar
    this->setPath();
}

void MainWindow::on_buttonForward_clicked()
{
    // Track dir
    QString dir;

    // If there is a Forward
    if(folderForwardHistory->size() > 0)
    {
        // Get first item of the forward stack
        dir = folderForwardHistory->pop();

        // Append dir to folderHistory
        folderHistory->append(dir);

        // Set root index
        ui->treeViewExplorer->setRootIndex(model->index(dir));

    }

    // Show path in status bar
    this->setPath();
}

void MainWindow::on_actionOpen_triggered()
{
    DialogOpen *open = new DialogOpen(this);

    open->exec();
}

void MainWindow::on_actionNew_triggered()
{
    DialogNew *newDialog = new DialogNew(this);

    newDialog->exec();
}

void MainWindow::setPath()
{
    // Show message
    ui->statusBar->showMessage(folderHistory->last());

    // At last item? Disable back button.
    ui->buttonBack->setEnabled(folderHistory->size() > 1);

    // At last forward item? Disable forward button.
    ui->buttonForward->setEnabled(folderForwardHistory->size() > 0);
}
<commit_msg>Fixed File tree<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialogopen.h"
#include "dialognew.h"

#include <QFileSystemModel>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    folderHistory(new QStack<QString>),
    folderForwardHistory(new QStack<QString>)
{
    // Setup the UI
    ui->setupUi(this);

    // Create file system models
    model = new QFileSystemModel(this);
    model->setRootPath(QDir::homePath());
    modelDirs = new QFileSystemModel(this);
    modelDirs->setRootPath("");
    modelDirs->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);

    // Set models in views
    ui->treeViewExplorer->setModel(model);
    ui->treeViewExplorer->setRootIndex(model->index(QDir::homePath()));
    ui->treeViewFiles->setModel(modelDirs);
    ui->treeViewFiles->hideColumn(3);
    ui->treeViewFiles->hideColumn(2);
    ui->treeViewFiles->hideColumn(1);

    // Add to stack
    folderHistory->append(QDir::homePath());

    // Show path in status bar
    this->setPath();
}

MainWindow::~MainWindow()
{
    delete ui;
    delete folderHistory;
    delete folderForwardHistory;
    delete model;
    delete modelDirs;
}

void MainWindow::on_treeViewExplorer_doubleClicked(const QModelIndex &index)
{
    // Get directory
    QString dir(model->filePath(index));

    // clear forward if it doesn't contain dir
    // else pop from ForwardHistory
    if (!folderForwardHistory->contains(dir)) folderForwardHistory->clear();
    else folderForwardHistory->pop();

    // Add to stack
    folderHistory->append(dir);

    // Set root index
    ui->treeViewExplorer->setRootIndex(model->index(dir));

    // Show path in status bar
    this->setPath();
}

void MainWindow::on_treeViewFiles_clicked(const QModelIndex &index)
{

    this->on_treeViewExplorer_doubleClicked(index);
}

void MainWindow::on_buttonBack_clicked()
{
    // Track dir
    QString dir;

    // More than only the home item
    if(folderHistory->size() > 0)
    {
        // Get the first item of the stack
        dir = folderHistory->pop();

        // Add to folderForwardHistory
        folderForwardHistory->append(dir);

        // Is it the current directory?
        if(folderHistory->size() > 0 && ui->treeViewExplorer->rootIndex() == model->index(dir)) {
            // Pop another
            dir = folderHistory->last();
        }

        // Set root index
        ui->treeViewExplorer->setRootIndex(model->index(dir));
    }

    // History empty?
    if(folderHistory->size() == 0)
    {
        // Append the last dir as it must be the starting point
        folderHistory->append(dir);
    }

    // Show path in status bar
    this->setPath();
}

void MainWindow::on_buttonForward_clicked()
{
    // Track dir
    QString dir;

    // If there is a Forward
    if(folderForwardHistory->size() > 0)
    {
        // Get first item of the forward stack
        dir = folderForwardHistory->pop();

        // Append dir to folderHistory
        folderHistory->append(dir);

        // Set root index
        ui->treeViewExplorer->setRootIndex(model->index(dir));

    }

    // Show path in status bar
    this->setPath();
}

void MainWindow::on_actionOpen_triggered()
{
    DialogOpen *open = new DialogOpen(this);

    open->exec();
}

void MainWindow::on_actionNew_triggered()
{
    DialogNew *newDialog = new DialogNew(this);

    newDialog->exec();
}

void MainWindow::setPath()
{
    // Show message
    ui->statusBar->showMessage(folderHistory->last());

    // At last item? Disable back button.
    ui->buttonBack->setEnabled(folderHistory->size() > 1);

    // At last forward item? Disable forward button.
    ui->buttonForward->setEnabled(folderForwardHistory->size() > 0);
}
<|endoftext|>


<commit_before>// Copyright 2014 Open Source Robotics Foundation, Inc.
//
// 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.

#include <iostream>
#include <memory>

#include <rclcpp/rclcpp.hpp>
#include <rclcpp/strategies/bounded_msg_memory_strategy.hpp>

#include <std_interfaces/msg/int32.hpp>
#include <std_interfaces/msg/string.hpp>

using namespace rclcpp::bounded_message_memory_strategy;

void chatterCallback(const std_interfaces::msg::Int32::ConstSharedPtr & msg)
{
  std::cout << "I heard: [" << msg->data << "]" << std::endl;
}

void chatterCallbackString(const std_interfaces::msg::String::ConstSharedPtr & msg)
{
  std::cout << "I heard: [" << msg->data << "]" << std::endl;
}

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  auto node = rclcpp::Node::make_shared("listener_bounded");

  BoundedMessageMemoryStrategy<std_interfaces::msg::Int32> msg_strategy;
  auto msg_strategy_ptr = std::make_shared<message_memory_strategy::MessageMemoryStrategy<std_interfaces::msg::Int32>>(msg_strategy);
  auto sub = node->create_subscription<std_interfaces::msg::Int32>("chatter", 7, chatterCallback, nullptr, false, msg_strategy_ptr);

  // If the following block is uncommented and the above block commented out, then the example will not compile.
  /*
  BoundedMessageMemoryStrategy<std_interfaces::msg::String> msg_strategy;
  auto msg_strategy_ptr = std::make_shared<message_memory_strategy::MessageMemoryStrategy<std_interfaces::msg::String>>(msg_strategy);
  auto sub = node->create_subscription<std_interfaces::msg::String>("chatter", 7, chatterCallbackString, nullptr, false, msg_strategy_ptr);
  */

  rclcpp::spin(node);

  return 0;
}
<commit_msg>take out some trash<commit_after><|endoftext|>


<commit_before>//
//  effect.cpp
//  emptyExample
//
//  Created by Mark van de Korput on 16-04-19.
//
//

#include "effects.hpp"
#include "shader_manager.hpp"
#include "video_manager.hpp"

using namespace of2030;

// int Effect::cidCounter = 0;

Effect::Effect(){
    reset();

    // every effect instance gets a unique cid (client-side-id)
    // cid = cidCounter;
    // cidCounter++;
}

void Effect::reset(){
    startTime = NO_TIME;
    endTime = NO_TIME;
    trigger = "";
    shader = NULL;
    video_player = NULL;
    mask_video_player = NULL;
    layer = 0;
    bUnique = true;
}

void Effect::update(float dt){
    auto_pos += auto_velocity * dt;
}

void Effect::setup(Context &_context){
    string val;

    bUnique = _context.effect_setting.getValue("unique", "1") == "0";

    // make sure we have a start time (default to NOW)
    if(!hasStartTime()){
        startTime = _context.time;
    }

    val = _context.effect_setting.getValue("operation", "");
    if(val != ""){
        if(val == "load_video"){
            val = _context.effect_setting.getValue("video", "");
            VideoManager::instance()->get(val, _context.effect_setting.getValue("video_alias", val), true);
        }

        if(val == "unload_video"){
            val = _context.effect_setting.getValue("video_alias", "");
            if(val == "")
                val = _context.effect_setting.getValue("video", "");
            VideoManager::instance()->unload(val);
        }

        truncate();
        return;
    }

    // make sure we have endTime and duration initialized AND consistent
    if(!hasEndTime() && _context.effect_setting.hasValue("duration")){
        setDuration(_context.effect_setting.getValue("duration", 30.0f));
    }

    // load/start/configure video if specified
    val = _context.effect_setting.getValue("video", "");
    if(val != ""){
        // load video (get video player instance from the VideoManager)
        video_player = VideoManager::instance()->get(val, _context.effect_setting.getValue("video_alias", val), true);

        if(video_player){
            if(_context.effect_setting.getValue("loop", "0") == "1"){
                // TODO; this player might currently be used by other effects?
                video_player->setLoopState(OF_LOOP_NORMAL);
                // indefinite
                endTime = NO_TIME;
            } else {
                // set none-looping
                video_player->setLoopState(OF_LOOP_NONE);

                // wanna freeze on first or last frame when done? remove end time, go on indefinite
                if(_context.effect_setting.hasValue("freeze")){
                    endTime = NO_TIME;
                }

                // video_player->getDuration() is causing problems on PI (maybe its the animation codec)
                // we'll just truncate in the draw function, when the end of the file is reached (and we're not feezing)
                /* else if(getDuration() > video_player->getDuration()){
                    // make sure the effect's duration time is not longer than the non-looping video's duration
                    setDuration(video_player->getDuration());
                }*/
            }

            // reset to start of video (this video player might have been used already by other effects
            if(_context.effect_setting.getValue("reset", "0") == "1"){
                video_player->setPosition(0.0);
            }

            video_player->play();
        } else {
            ofLogWarning() << "Effect::setup could not get video player for " << val;
            ofLog() << "setting effect duration to zero";
            // this will effectively abort the effect
            truncate();
        }
    }

    // load/start/configure video_mask if specified
    val = _context.effect_setting.getValue("video_mask", "");
    if(val != ""){
        if(val == "self"){
            mask_video_player = video_player;
        } else {
            // load video (get video player instance from the VideoManager)
            mask_video_player = VideoManager::instance()->get(val, _context.effect_setting.getValue("video_mask_alias", val), true);

            if(mask_video_player){
                if(_context.effect_setting.getValue("video_mask_loop", "0") == "1"){
                    // TODO; this player might currently be used by other effects?
                    mask_video_player->setLoopState(OF_LOOP_NORMAL);
                } else {
                    // set none-looping
                    mask_video_player->setLoopState(OF_LOOP_NONE);
                }

                // reset to start of video (this video player might have been used already by other effects
                if(_context.effect_setting.getValue("video_mask_reset", "0") == "1"){
                    mask_video_player->setPosition(0.0);
                }

                mask_video_player->play();
            }/* else {
                ofLogWarning() << "Effect::setup could not get video player for " << val;
                ofLog() << "setting effect duration to zero";
                // this will effectively abort the effect
                truncate();
            }*/
        }
    }

    // load any shaders based shader param
    val = _context.effect_setting.getValue("shader", "");
    if(val != ""){
        this->shader = ShaderManager::instance()->get(val);
    }

    auto_pos = _context.effect_setting.getValue("auto_pos", ofVec3f(0.0f));
    auto_velocity = _context.effect_setting.getValue("auto_velocity", ofVec3f(0.0f));

    layer = _context.effect_setting.getValue("layer", 0);
}

void Effect::draw(Context &_context){
    // make some context, logic and precalculate data available to the entire class
    PreCalc prec;
    prec.load(_context);
    context = &_context;
    precalc = ≺
    string val;

    // this value can be updates during the effect (was already initialized in setup())
    auto_velocity = _context.effect_setting.getValue("auto_velocity", ofVec3f(0.0f));

    ofShader* maskShader = ShaderManager::instance()->get("mask");

    // draw 4-point coordinate mask in fbo2
    context->fbo2->begin();
        ofClear(0.0f, 0.0f, 0.0f, 0.0f);
        ofSetColor(255);

        val = context->effect_setting.getValue("mask_coords_name", "");
        if(val != ""){
            // draw 4-point coordinates mask
            // (if no coordinates specfied, this will give a full white frame)
            drawMask(val);
        } else {
            ofRectangle rect = precalc->panoTunnelDrawRect();
            ofDrawRectangle(rect);
        }
    context->fbo2->end();

    // draw content to fbo3
    context->fbo3->begin();
        ofClear(0.0f, 0.0f, 0.0f, 0.0f);
        ofSetColor(255);
        ofPushMatrix();
            drawContent();
        ofPopMatrix();
    context->fbo3->end();

    // draw content of fbo3 through mask of fbo2
    maskShader->begin();
        // pass mask texture to shader
        maskShader->setUniformTexture("iMask", context->fbo2->getTexture(), 2);
        // ofSetColor(precalc->color); / --> doesn't work because shader doesn't use this color
        context->fbo3->draw(0.0f, 0.0f);
    maskShader->end();

    context = NULL;
    precalc = NULL;
}

void Effect::drawContent(){
    string val;

    // ofTranslate(context->effect_setting.getValue("translate", ofVec3f(0.0)) * precalc->worldToScreenVec2f);
    // ofScale(context->effect_setting.getValue("scale", ofVec3f(1.0)));

    ofRotateX(precalc->rotate.x);
    ofRotateY(precalc->rotate.y);
    ofRotateZ(precalc->rotate.z);
    ofScale(precalc->scale);
    ofTranslate(precalc->translate);

    ofRotateX(precalc->effect_rotate.x);
    ofRotateY(precalc->effect_rotate.y);
    ofRotateZ(precalc->effect_rotate.z);
    ofScale(precalc->effect_scale);
    ofTranslate(precalc->effect_translate + auto_pos);

    // draw; video?
    if(video_player){
        if(!(video_player->isLoaded() && video_player->getTexture().isAllocated())){
            return;
        }

        // movie done?
        if(video_player->getIsMovieDone() && context->effect_setting.getValue("loop", "0") != "1"){
            // if effect is configured to free (at first or last frame)
            val = context->effect_setting.getValue("freeze", "");
            if(val == "first"){
                video_player->setPosition(0.0);
                //video_player->setPaused(true);
            // no freezing; end effect
            } else if(val == ""){
                truncate(); // end this effect
                return;
            }
        }

        bool bAlphaBlack = (context->effect_setting.getValue("alphablack", "0") == "1");
        ofShader* vidShader;

        if(mask_video_player){
            if(!(mask_video_player->isLoaded() && mask_video_player->getTexture().isAllocated())){
                return;
            }

            if(mask_video_player->getIsMovieDone() && context->effect_setting.getValue("video_mask_loop", "0") != "1"){
                float freeze_pos = context->effect_setting.getValue("video_mask_freeze", -1.0f);
                if(freeze_pos >= 0.0f){
                    mask_video_player->setPosition(freeze_pos);
                }
            }

            vidShader = ShaderManager::instance()->get("mask");
            vidShader->begin();
            vidShader->setUniformTexture("iMask", mask_video_player->getTexture(), 2);
        }

        // draw video texture
        video_player->draw(0.0, 0.0, precalc->scrDrawSize.x, precalc->scrDrawSize.y);

        if(mask_video_player){
            vidShader->end();
        }

        return;
    }

    // not video

    if(shader){
        // activate shader
        shader->begin();

        // populate shader
        shader->setUniform2f("iResolution", precalc->resolution);
        shader->setUniform3f("iPos", context->effect_setting.getValue("pos", ofVec3f(0.0f)));
        shader->setUniform3f("iSize", context->effect_setting.getValue("size", ofVec3f(0.0f)));
        shader->setUniform1f("iProgress", getProgress());
        shader->setUniform1f("iDuration", getDuration());
        shader->setUniform2f("iScreenWorldSize", precalc->scrWorldSize);
        shader->setUniform1f("iGain", context->effect_setting.getValue("gain", 1.0f));
    }

    string pattern = context->effect_setting.getValue("pattern", "");

    // pattern?
    if(pattern != ""){
        drawPattern(pattern);
    // simple rectangle
    } else {
        ofSetColor(precalc->color);
        ofDrawRectangle(0.0f, 0.0f, precalc->scrDrawSize.x, precalc->scrDrawSize.y);
    }

    if(shader){
        // deactivate shader
        shader->end();
    }
}

void Effect::drawPattern(const string &patternName){
    //
    // SPOT
    //

    if(patternName == "spot"){
        int spotNumber = context->effect_setting.getValue("spot", (int)1);
        string prefix = "spot" + ofToString(spotNumber);

        ofVec2f spotPos = context->screen_setting.getValue(prefix, ofVec2f(-10.0f)) * precalc->resolution;
        ofVec2f spotSize = context->screen_setting.getValue(prefix+"size", ofVec2f(0.0f)) * precalc->resolution;

        ofVec2f fxSpotPos = context->effect_setting.getValue("pos", ofVec2f(0.0f, 0.0f));

        // spot reposition according to effect setting (interpret as real-world-meters)
        spotPos += fxSpotPos / precalc->scrWorldSize * precalc->resolution;

        if(!shader){
            // draw without shader stuff
            // ofDrawRectangle(0, 0, precalc->resolution.x, precalc->resolution.y);
            ofDrawEllipse(0.0f, 0.0f, precalc->scrDrawSize.x, precalc->scrDrawSize.y);
            return;
        }

        // shader is already activated, just add some params

        //    shader->setUniform2f("iResolution", precalc->resolution);
        shader->setUniform2f("iSpotPos", spotPos);
        shader->setUniform2f("iSpotSize", spotSize);
        shader->setUniform1f("iGain", context->effect_setting.getValue("gain", 1.0f));

        // quarter; 1 means top right, 2 means bottom right, 3 bottom left, 4 means top left, zero means none
        int q = context->effect_setting.getValue("quarter_on", 0);
        shader->setUniform1i("iQuarterOn", q);
        q = context->effect_setting.getValue("quarter_off", 0);
        shader->setUniform1i("iQuarterOff", q);

        spotPos = spotPos - spotSize * 0.5;
        ofDrawRectangle(0.0f, 0.0f, precalc->scrDrawSize.x, precalc->scrDrawSize.y);
        return;
    }

    //
    // POS
    //

    if(patternName == "pos"){
        ofVec3f lightpos = context->effect_setting.getValue("pos", ofVec3f(0.0f, 0.0f, 0.0f));
        float lightsize = context->effect_setting.getValue("size", 0.0f);
        ofVec3f mypos = context->screen_setting.getValue("pos", ofVec3f(0.0f, 0.0f, 0.0f));
        float onDistance = context->effect_setting.getValue("on_distance", 3.0f);
        float offDistance = context->effect_setting.getValue("off_distance", 9.0f);
        float distance = mypos.distance(lightpos) - lightsize;
        float gain = ofMap(distance, onDistance, offDistance, 255, 0, true);

        ofSetColor(255, 255, 255, gain);
        ofDrawRectangle(0, 0, precalc->scrDrawSize.x, precalc->scrDrawSize.y);
        return;
    }

}

void Effect::drawMask(const string &coordsName){
    ofVec2f coords[4];

    coords[0] = context->screen_setting.getValue(coordsName+"1", ofVec2f(0.0f, 1.0f)) * precalc->resolution;
    coords[1] = context->screen_setting.getValue(coordsName+"2", ofVec2f(1.0f, 1.0f)) * precalc->resolution;
    coords[2] = context->screen_setting.getValue(coordsName+"3", ofVec2f(1.0f, 0.0f)) * precalc->resolution;
    coords[3] = context->screen_setting.getValue(coordsName+"4", ofVec2f(0.0f, 0.0f)) * precalc->resolution;

    // draw mask content
    ofDrawTriangle(coords[0].x, coords[0].y, coords[1].x, coords[1].y, coords[2].x, coords[2].y);
    ofDrawTriangle(coords[0].x, coords[0].y, coords[2].x, coords[2].y, coords[3].x, coords[3].y);
}
<commit_msg>freeze at any pos (not just first or last)<commit_after>//
//  effect.cpp
//  emptyExample
//
//  Created by Mark van de Korput on 16-04-19.
//
//

#include "effects.hpp"
#include "shader_manager.hpp"
#include "video_manager.hpp"

using namespace of2030;

// int Effect::cidCounter = 0;

Effect::Effect(){
    reset();

    // every effect instance gets a unique cid (client-side-id)
    // cid = cidCounter;
    // cidCounter++;
}

void Effect::reset(){
    startTime = NO_TIME;
    endTime = NO_TIME;
    trigger = "";
    shader = NULL;
    video_player = NULL;
    mask_video_player = NULL;
    layer = 0;
    bUnique = true;
}

void Effect::update(float dt){
    auto_pos += auto_velocity * dt;
}

void Effect::setup(Context &_context){
    string val;

    bUnique = _context.effect_setting.getValue("unique", "1") == "0";

    // make sure we have a start time (default to NOW)
    if(!hasStartTime()){
        startTime = _context.time;
    }

    val = _context.effect_setting.getValue("operation", "");
    if(val != ""){
        if(val == "load_video"){
            val = _context.effect_setting.getValue("video", "");
            VideoManager::instance()->get(val, _context.effect_setting.getValue("video_alias", val), true);
        }

        if(val == "unload_video"){
            val = _context.effect_setting.getValue("video_alias", "");
            if(val == "")
                val = _context.effect_setting.getValue("video", "");
            VideoManager::instance()->unload(val);
        }

        truncate();
        return;
    }

    // make sure we have endTime and duration initialized AND consistent
    if(!hasEndTime() && _context.effect_setting.hasValue("duration")){
        setDuration(_context.effect_setting.getValue("duration", 30.0f));
    }

    // load/start/configure video if specified
    val = _context.effect_setting.getValue("video", "");
    if(val != ""){
        // load video (get video player instance from the VideoManager)
        video_player = VideoManager::instance()->get(val, _context.effect_setting.getValue("video_alias", val), true);

        if(video_player){
            if(_context.effect_setting.getValue("loop", "0") == "1"){
                // TODO; this player might currently be used by other effects?
                video_player->setLoopState(OF_LOOP_NORMAL);
                // indefinite
                endTime = NO_TIME;
            } else {
                // set none-looping
                video_player->setLoopState(OF_LOOP_NONE);

                // wanna freeze on a frame when done? remove end time, go on indefinite
                if(_context.effect_setting.hasValue("freeze")){
                    endTime = NO_TIME;
                }

                // video_player->getDuration() is causing problems on PI (maybe its the animation codec)
                // we'll just truncate in the draw function, when the end of the file is reached (and we're not feezing)
                /* else if(getDuration() > video_player->getDuration()){
                    // make sure the effect's duration time is not longer than the non-looping video's duration
                    setDuration(video_player->getDuration());
                }*/
            }

            // reset to start of video (this video player might have been used already by other effects
            if(_context.effect_setting.getValue("reset", "0") == "1"){
                video_player->setPosition(0.0);
            }

            video_player->play();
        } else {
            ofLogWarning() << "Effect::setup could not get video player for " << val;
            ofLog() << "setting effect duration to zero";
            // this will effectively abort the effect
            truncate();
        }
    }

    // load/start/configure video_mask if specified
    val = _context.effect_setting.getValue("video_mask", "");
    if(val != ""){
        if(val == "self"){
            mask_video_player = video_player;
        } else {
            // load video (get video player instance from the VideoManager)
            mask_video_player = VideoManager::instance()->get(val, _context.effect_setting.getValue("video_mask_alias", val), true);

            if(mask_video_player){
                if(_context.effect_setting.getValue("video_mask_loop", "0") == "1"){
                    // TODO; this player might currently be used by other effects?
                    mask_video_player->setLoopState(OF_LOOP_NORMAL);
                } else {
                    // set none-looping
                    mask_video_player->setLoopState(OF_LOOP_NONE);
                }

                // reset to start of video (this video player might have been used already by other effects
                if(_context.effect_setting.getValue("video_mask_reset", "0") == "1"){
                    mask_video_player->setPosition(0.0);
                }

                mask_video_player->play();
            }/* else {
                ofLogWarning() << "Effect::setup could not get video player for " << val;
                ofLog() << "setting effect duration to zero";
                // this will effectively abort the effect
                truncate();
            }*/
        }
    }

    // load any shaders based shader param
    val = _context.effect_setting.getValue("shader", "");
    if(val != ""){
        this->shader = ShaderManager::instance()->get(val);
    }

    auto_pos = _context.effect_setting.getValue("auto_pos", ofVec3f(0.0f));
    auto_velocity = _context.effect_setting.getValue("auto_velocity", ofVec3f(0.0f));

    layer = _context.effect_setting.getValue("layer", 0);
}

void Effect::draw(Context &_context){
    // make some context, logic and precalculate data available to the entire class
    PreCalc prec;
    prec.load(_context);
    context = &_context;
    precalc = ≺
    string val;

    // this value can be updates during the effect (was already initialized in setup())
    auto_velocity = _context.effect_setting.getValue("auto_velocity", ofVec3f(0.0f));

    ofShader* maskShader = ShaderManager::instance()->get("mask");

    // draw 4-point coordinate mask in fbo2
    context->fbo2->begin();
        ofClear(0.0f, 0.0f, 0.0f, 0.0f);
        ofSetColor(255);

        val = context->effect_setting.getValue("mask_coords_name", "");
        if(val != ""){
            // draw 4-point coordinates mask
            // (if no coordinates specfied, this will give a full white frame)
            drawMask(val);
        } else {
            ofRectangle rect = precalc->panoTunnelDrawRect();
            ofDrawRectangle(rect);
        }
    context->fbo2->end();

    // draw content to fbo3
    context->fbo3->begin();
        ofClear(0.0f, 0.0f, 0.0f, 0.0f);
        ofSetColor(255);
        ofPushMatrix();
            drawContent();
        ofPopMatrix();
    context->fbo3->end();

    // draw content of fbo3 through mask of fbo2
    maskShader->begin();
        // pass mask texture to shader
        maskShader->setUniformTexture("iMask", context->fbo2->getTexture(), 2);
        // ofSetColor(precalc->color); / --> doesn't work because shader doesn't use this color
        context->fbo3->draw(0.0f, 0.0f);
    maskShader->end();

    context = NULL;
    precalc = NULL;
}

void Effect::drawContent(){
    string val;

    // ofTranslate(context->effect_setting.getValue("translate", ofVec3f(0.0)) * precalc->worldToScreenVec2f);
    // ofScale(context->effect_setting.getValue("scale", ofVec3f(1.0)));

    ofRotateX(precalc->rotate.x);
    ofRotateY(precalc->rotate.y);
    ofRotateZ(precalc->rotate.z);
    ofScale(precalc->scale);
    ofTranslate(precalc->translate);

    ofRotateX(precalc->effect_rotate.x);
    ofRotateY(precalc->effect_rotate.y);
    ofRotateZ(precalc->effect_rotate.z);
    ofScale(precalc->effect_scale);
    ofTranslate(precalc->effect_translate + auto_pos);

    // draw; video?
    if(video_player){
        if(!(video_player->isLoaded() && video_player->getTexture().isAllocated())){
            return;
        }

        // movie done?
        if(video_player->getIsMovieDone() && context->effect_setting.getValue("loop", "0") != "1"){
            // if effect is configured to freeze (at certain position, usually first or last frame)
            float freeze_pos = context->effect_setting.getValue("freeze", (float)-1.0);
            if(freeze_pos >= 0.0f){
                video_player->setPosition(freeze_pos);
                video_player->setPaused(true);
            // no freezing; end effect
            } else {
                truncate(); // end this effect
                return;
            }
        }

        bool bAlphaBlack = (context->effect_setting.getValue("alphablack", "0") == "1");
        ofShader* vidShader;

        if(mask_video_player){
            if(!(mask_video_player->isLoaded() && mask_video_player->getTexture().isAllocated())){
                return;
            }

            if(mask_video_player->getIsMovieDone() && context->effect_setting.getValue("video_mask_loop", "0") != "1"){
                float freeze_pos = context->effect_setting.getValue("video_mask_freeze", -1.0f);
                if(freeze_pos >= 0.0f){
                    mask_video_player->setPosition(freeze_pos);
                }
            }

            vidShader = ShaderManager::instance()->get("mask");
            vidShader->begin();
            vidShader->setUniformTexture("iMask", mask_video_player->getTexture(), 2);
        }

        // draw video texture
        video_player->draw(0.0, 0.0, precalc->scrDrawSize.x, precalc->scrDrawSize.y);

        if(mask_video_player){
            vidShader->end();
        }

        return;
    }

    // not video

    if(shader){
        // activate shader
        shader->begin();

        // populate shader
        shader->setUniform2f("iResolution", precalc->resolution);
        shader->setUniform3f("iPos", context->effect_setting.getValue("pos", ofVec3f(0.0f)));
        shader->setUniform3f("iSize", context->effect_setting.getValue("size", ofVec3f(0.0f)));
        shader->setUniform1f("iProgress", getProgress());
        shader->setUniform1f("iDuration", getDuration());
        shader->setUniform2f("iScreenWorldSize", precalc->scrWorldSize);
        shader->setUniform1f("iGain", context->effect_setting.getValue("gain", 1.0f));
    }

    string pattern = context->effect_setting.getValue("pattern", "");

    // pattern?
    if(pattern != ""){
        drawPattern(pattern);
    // simple rectangle
    } else {
        ofSetColor(precalc->color);
        ofDrawRectangle(0.0f, 0.0f, precalc->scrDrawSize.x, precalc->scrDrawSize.y);
    }

    if(shader){
        // deactivate shader
        shader->end();
    }
}

void Effect::drawPattern(const string &patternName){
    //
    // SPOT
    //

    if(patternName == "spot"){
        int spotNumber = context->effect_setting.getValue("spot", (int)1);
        string prefix = "spot" + ofToString(spotNumber);

        ofVec2f spotPos = context->screen_setting.getValue(prefix, ofVec2f(-10.0f)) * precalc->resolution;
        ofVec2f spotSize = context->screen_setting.getValue(prefix+"size", ofVec2f(0.0f)) * precalc->resolution;

        ofVec2f fxSpotPos = context->effect_setting.getValue("pos", ofVec2f(0.0f, 0.0f));

        // spot reposition according to effect setting (interpret as real-world-meters)
        spotPos += fxSpotPos / precalc->scrWorldSize * precalc->resolution;

        if(!shader){
            // draw without shader stuff
            // ofDrawRectangle(0, 0, precalc->resolution.x, precalc->resolution.y);
            ofDrawEllipse(0.0f, 0.0f, precalc->scrDrawSize.x, precalc->scrDrawSize.y);
            return;
        }

        // shader is already activated, just add some params

        //    shader->setUniform2f("iResolution", precalc->resolution);
        shader->setUniform2f("iSpotPos", spotPos);
        shader->setUniform2f("iSpotSize", spotSize);
        shader->setUniform1f("iGain", context->effect_setting.getValue("gain", 1.0f));

        // quarter; 1 means top right, 2 means bottom right, 3 bottom left, 4 means top left, zero means none
        int q = context->effect_setting.getValue("quarter_on", 0);
        shader->setUniform1i("iQuarterOn", q);
        q = context->effect_setting.getValue("quarter_off", 0);
        shader->setUniform1i("iQuarterOff", q);

        spotPos = spotPos - spotSize * 0.5;
        ofDrawRectangle(0.0f, 0.0f, precalc->scrDrawSize.x, precalc->scrDrawSize.y);
        return;
    }

    //
    // POS
    //

    if(patternName == "pos"){
        ofVec3f lightpos = context->effect_setting.getValue("pos", ofVec3f(0.0f, 0.0f, 0.0f));
        float lightsize = context->effect_setting.getValue("size", 0.0f);
        ofVec3f mypos = context->screen_setting.getValue("pos", ofVec3f(0.0f, 0.0f, 0.0f));
        float onDistance = context->effect_setting.getValue("on_distance", 3.0f);
        float offDistance = context->effect_setting.getValue("off_distance", 9.0f);
        float distance = mypos.distance(lightpos) - lightsize;
        float gain = ofMap(distance, onDistance, offDistance, 255, 0, true);

        ofSetColor(255, 255, 255, gain);
        ofDrawRectangle(0, 0, precalc->scrDrawSize.x, precalc->scrDrawSize.y);
        return;
    }

}

void Effect::drawMask(const string &coordsName){
    ofVec2f coords[4];

    coords[0] = context->screen_setting.getValue(coordsName+"1", ofVec2f(0.0f, 1.0f)) * precalc->resolution;
    coords[1] = context->screen_setting.getValue(coordsName+"2", ofVec2f(1.0f, 1.0f)) * precalc->resolution;
    coords[2] = context->screen_setting.getValue(coordsName+"3", ofVec2f(1.0f, 0.0f)) * precalc->resolution;
    coords[3] = context->screen_setting.getValue(coordsName+"4", ofVec2f(0.0f, 0.0f)) * precalc->resolution;

    // draw mask content
    ofDrawTriangle(coords[0].x, coords[0].y, coords[1].x, coords[1].y, coords[2].x, coords[2].y);
    ofDrawTriangle(coords[0].x, coords[0].y, coords[2].x, coords[2].y, coords[3].x, coords[3].y);
}
<|endoftext|>


<commit_before>#define _CRT_SECURE_NO_WARNINGS		// stop warning on fopen
#include <stdio.h>
#include <vector>
#include <chrono>
#include <assert.h>
#include <immintrin.h>

std::vector<unsigned char> LoadFile(const char *name)
{
	FILE * f = fopen(name, "rb");
	fseek(f, 0, SEEK_END);
	size_t len = ftell(f);
	fseek(f, 0, SEEK_SET);
	std::vector<unsigned char> buf;
	buf.resize(len);
	size_t r = fread((void *)&buf[0], 1, len, f);
	if (r != len)
	{
		printf("Read failed for %s", name);
		exit(1);
	}
	fclose(f);

	return buf;
}

int BigLong(const std::vector<unsigned char> &vec, int ofs)
{
	return (vec[ofs] << 24) + (vec[ofs + 1] << 16) + (vec[ofs + 2] << 8) + vec[ofs + 3];
}

const int NumDimensions = 28 * 28;

void TestBestMatch()
{
	std::vector<unsigned char>	testImages = LoadFile("t10k-images.idx3-ubyte");
	std::vector<unsigned char>	testLabels = LoadFile("t10k-labels.idx1-ubyte");
	std::vector<unsigned char>	trainImages = LoadFile("train-images.idx3-ubyte");
	std::vector<unsigned char>	trainLabels = LoadFile("train-labels.idx1-ubyte");

	int trainCount = BigLong(trainImages, 4);
	int testCount = BigLong(testImages, 4) >> 5;	// shrink for faster tests

	int	miss = 0;
	for (int i = 0; i < testCount; i++)
	{
		unsigned char label = testLabels[8 + i];
		assert(label >= 0 && label <= 9);
		const unsigned char * testData = &testImages[16 + i*NumDimensions];

		int bestLabel = -1;
		int bestError = INT_MAX;
		for (int j = 0; j < trainCount; j++)
		{
			const unsigned char * trainData = &trainImages[16 + j*NumDimensions];
			int error = 0;
			for (int k = 0; k < NumDimensions; k++)
			{
				const int v = (int)testData[k] - (int)trainData[k];
				error += v * v;
			}
			//5739837, 7025841, 5795133, 6536253, 5500006
			//6093159, 5652340, 6993727, 4700000, 5134448
			if (error < bestError)
			{
				bestError = error;
				bestLabel = trainLabels[8 + j];
			}
		}
		if (bestLabel != label)
		{
			miss++;
		}
	}
	printf("%i misses for accuracy: %f\n", miss, (float)(testCount - miss) / (float)testCount);
}

void TestBestMatchOpt1()
{
	std::vector<unsigned char>	testImages = LoadFile("t10k-images.idx3-ubyte");
	std::vector<unsigned char>	testLabels = LoadFile("t10k-labels.idx1-ubyte");
	std::vector<unsigned char>	trainImages = LoadFile("train-images.idx3-ubyte");
	std::vector<unsigned char>	trainLabels = LoadFile("train-labels.idx1-ubyte");

	int trainCount = BigLong(trainImages, 4);
	int testCount = BigLong(testImages, 4) >> 5;	// shrink for faster tests

	__m128i shuffle = _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);

	int	miss = 0;
	for (int i = 0; i < testCount; i++)
	{
		unsigned char label = testLabels[8 + i];
		assert(label >= 0 && label <= 9);
		const unsigned char * testData = &testImages[16 + i*NumDimensions];

		int bestLabel = -1;
		int bestError = INT_MAX;
		__m256i zero = _mm256_setzero_si256();
		for (int j = 0; j < trainCount; j++)
		{
			const unsigned char * trainData = &trainImages[16 + j*NumDimensions];
			__m256i error8 = _mm256_setzero_si256();
			for (int k = 0; k < NumDimensions; k+=16)
			{
				__m128i test8 = _mm_load_si128((const __m128i*)(testData+k));
				__m128i train8 = _mm_load_si128((const __m128i*)(trainData+k));
				__m256i test32l = _mm256_cvtepu8_epi32(test8);
				__m256i train32l = _mm256_cvtepu8_epi32(train8);

				test8 = _mm_shuffle_epi8(test8, shuffle);
				train8 = _mm_shuffle_epi8(train8, shuffle);
				__m256i test32h = _mm256_cvtepu8_epi32(test8);
				__m256i train32h = _mm256_cvtepu8_epi32(train8);

				__m256i diffl = _mm256_sub_epi32(test32l, train32l);
				__m256i diffh = _mm256_sub_epi32(test32h, train32h);

				__m256i squaredl = _mm256_mullo_epi32(diffl, diffl);
				__m256i squaredh = _mm256_mullo_epi32(diffh, diffh);

				error8 = _mm256_add_epi32(error8, squaredl);
				error8 = _mm256_add_epi32(error8, squaredh);
			}
			__m256i error4 = _mm256_hadd_epi32(error8, zero);
			__m256i error2 = _mm256_hadd_epi32(error4, zero); //error2 has 2 partial sums in 0 and 4
			__m128i error2l = _mm256_extracti128_si256(error2, 0);
			__m128i error2h = _mm256_extracti128_si256(error2, 1);
			__m128i error1 = _mm_add_epi32(error2l, error2h);

			int error = _mm_cvtsi128_si32(error1);
			//5739837, 7025841, 5795133, 6536253, 5500006
			//6093159, 5652340, 6993727, 4700000, 5134448
			if (error < bestError)
			{
				bestError = error;
				bestLabel = trainLabels[8 + j];
			}
		}
		if (bestLabel != label)
		{
			//115, 195, 241, 268, 300
			miss++;
		}
	}
	printf("%i misses for accuracy: %f\n", miss, (float)(testCount - miss) / (float)testCount);
}

void TestBestMatchOpt2()
{
	std::vector<unsigned char>	testImages = LoadFile("t10k-images.idx3-ubyte");
	std::vector<unsigned char>	testLabels = LoadFile("t10k-labels.idx1-ubyte");
	std::vector<unsigned char>	trainImages = LoadFile("train-images.idx3-ubyte");
	std::vector<unsigned char>	trainLabels = LoadFile("train-labels.idx1-ubyte");

	int trainCount = BigLong(trainImages, 4);
	int testCount = BigLong(testImages, 4) >> 5;	// shrink for faster tests

	__m128i shuffle = _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);

	int	miss = 0;
	for (int i = 0; i < testCount; i++)
	{
		unsigned char label = testLabels[8 + i];
		assert(label >= 0 && label <= 9);
		const unsigned char * testData = &testImages[16 + i*NumDimensions];

		int bestLabel = -1;
		int bestError = INT_MAX;
		__m256i zero = _mm256_setzero_si256();
		for (int j = 0; j < trainCount; j++)
		{
			const unsigned char * trainData = &trainImages[16 + j*NumDimensions];
			__m256i error8 = _mm256_setzero_si256();
			for (int k = 0; k < NumDimensions; k += 16)
			{
				__m128i test8 = _mm_load_si128((const __m128i*)(testData + k));
				__m128i train8 = _mm_load_si128((const __m128i*)(trainData + k));
				__m256i test32l = _mm256_cvtepu8_epi32(test8);
				__m256i train32l = _mm256_cvtepu8_epi32(train8);

				test8 = _mm_shuffle_epi8(test8, shuffle);
				train8 = _mm_shuffle_epi8(train8, shuffle);
				__m256i test32h = _mm256_cvtepu8_epi32(test8);
				__m256i train32h = _mm256_cvtepu8_epi32(train8);

				__m256i diffl = _mm256_sub_epi32(test32l, train32l);
				__m256i diffh = _mm256_sub_epi32(test32h, train32h);

				__m256i squaredl = _mm256_mullo_epi32(diffl, diffl);
				__m256i squaredh = _mm256_mullo_epi32(diffh, diffh);

				error8 = _mm256_add_epi32(error8, squaredl);
				error8 = _mm256_add_epi32(error8, squaredh);
			}
			__m256i error4 = _mm256_hadd_epi32(error8, zero);
			__m256i error2 = _mm256_hadd_epi32(error4, zero); //error2 has 2 partial sums in 0 and 4
			__m128i error2l = _mm256_extracti128_si256(error2, 0);
			__m128i error2h = _mm256_extracti128_si256(error2, 1);
			__m128i error1 = _mm_add_epi32(error2l, error2h);

			int error = _mm_cvtsi128_si32(error1);
			//5739837, 7025841, 5795133, 6536253, 5500006
			//6093159, 5652340, 6993727, 4700000, 5134448
			if (error < bestError)
			{
				bestError = error;
				bestLabel = trainLabels[8 + j];
			}
		}
		if (bestLabel != label)
		{
			//115, 195, 241, 268, 300
			miss++;
		}
	}
	printf("%i misses for accuracy: %f\n", miss, (float)(testCount - miss) / (float)testCount);
}

int main(int argc, char ** argv)
{
	std::chrono::time_point<std::chrono::system_clock> start, end;

	start = std::chrono::system_clock::now();
	//TestBestMatch();
	end = std::chrono::system_clock::now();
	std::chrono::duration<double> elapsed_seconds = end - start;
	printf("%f seconds\n", elapsed_seconds.count());

	start = std::chrono::system_clock::now();
	//TestBestMatchOpt1();
	end = std::chrono::system_clock::now();
	elapsed_seconds = end - start;
	printf("%f seconds\n", elapsed_seconds.count());

	start = std::chrono::system_clock::now();
	TestBestMatchOpt2();
	end = std::chrono::system_clock::now();
	elapsed_seconds = end - start;
	printf("%f seconds\n", elapsed_seconds.count());
}<commit_msg>trying to make use of the extra registers in 64bit, only helped 5-10%, and a little slower in 32 bit<commit_after>#define _CRT_SECURE_NO_WARNINGS		// stop warning on fopen
#include <stdio.h>
#include <vector>
#include <chrono>
#include <assert.h>
#include <immintrin.h>

std::vector<unsigned char> LoadFile(const char *name)
{
	FILE * f = fopen(name, "rb");
	fseek(f, 0, SEEK_END);
	size_t len = ftell(f);
	fseek(f, 0, SEEK_SET);
	std::vector<unsigned char> buf;
	buf.resize(len);
	size_t r = fread((void *)&buf[0], 1, len, f);
	if (r != len)
	{
		printf("Read failed for %s", name);
		exit(1);
	}
	fclose(f);

	return buf;
}

int BigLong(const std::vector<unsigned char> &vec, int ofs)
{
	return (vec[ofs] << 24) + (vec[ofs + 1] << 16) + (vec[ofs + 2] << 8) + vec[ofs + 3];
}

const int NumDimensions = 28 * 28;

void TestBestMatch()
{
	std::vector<unsigned char>	testImages = LoadFile("t10k-images.idx3-ubyte");
	std::vector<unsigned char>	testLabels = LoadFile("t10k-labels.idx1-ubyte");
	std::vector<unsigned char>	trainImages = LoadFile("train-images.idx3-ubyte");
	std::vector<unsigned char>	trainLabels = LoadFile("train-labels.idx1-ubyte");

	int trainCount = BigLong(trainImages, 4);
	int testCount = BigLong(testImages, 4) >> 5;	// shrink for faster tests

	int	miss = 0;
	for (int i = 0; i < testCount; i++)
	{
		unsigned char label = testLabels[8 + i];
		assert(label >= 0 && label <= 9);
		const unsigned char * testData = &testImages[16 + i*NumDimensions];

		int bestLabel = -1;
		int bestError = INT_MAX;
		for (int j = 0; j < trainCount; j++)
		{
			const unsigned char * trainData = &trainImages[16 + j*NumDimensions];
			int error = 0;
			for (int k = 0; k < NumDimensions; k++)
			{
				const int v = (int)testData[k] - (int)trainData[k];
				error += v * v;
			}
			//5739837, 7025841, 5795133, 6536253, 5500006
			//6093159, 5652340, 6993727, 4700000, 5134448
			if (error < bestError)
			{
				bestError = error;
				bestLabel = trainLabels[8 + j];
			}
		}
		if (bestLabel != label)
		{
			miss++;
		}
	}
	printf("%i misses for accuracy: %f\n", miss, (float)(testCount - miss) / (float)testCount);
}

void TestBestMatchOpt1()
{
	std::vector<unsigned char>	testImages = LoadFile("t10k-images.idx3-ubyte");
	std::vector<unsigned char>	testLabels = LoadFile("t10k-labels.idx1-ubyte");
	std::vector<unsigned char>	trainImages = LoadFile("train-images.idx3-ubyte");
	std::vector<unsigned char>	trainLabels = LoadFile("train-labels.idx1-ubyte");

	int trainCount = BigLong(trainImages, 4);
	int testCount = BigLong(testImages, 4) >> 5;	// shrink for faster tests

	__m128i shuffle = _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);

	int	miss = 0;
	for (int i = 0; i < testCount; i++)
	{
		unsigned char label = testLabels[8 + i];
		assert(label >= 0 && label <= 9);
		const unsigned char * testData = &testImages[16 + i*NumDimensions];

		int bestLabel = -1;
		int bestError = INT_MAX;
		__m256i zero = _mm256_setzero_si256();
		for (int j = 0; j < trainCount; j++)
		{
			const unsigned char * trainData = &trainImages[16 + j*NumDimensions];
			__m256i error8 = _mm256_setzero_si256();
			for (int k = 0; k < NumDimensions; k+=16)
			{
				__m128i test8 = _mm_load_si128((const __m128i*)(testData+k));
				__m128i train8 = _mm_load_si128((const __m128i*)(trainData+k));
				__m256i test32l = _mm256_cvtepu8_epi32(test8);
				__m256i train32l = _mm256_cvtepu8_epi32(train8);

				test8 = _mm_shuffle_epi8(test8, shuffle);
				train8 = _mm_shuffle_epi8(train8, shuffle);
				__m256i test32h = _mm256_cvtepu8_epi32(test8);
				__m256i train32h = _mm256_cvtepu8_epi32(train8);

				__m256i diffl = _mm256_sub_epi32(test32l, train32l);
				__m256i diffh = _mm256_sub_epi32(test32h, train32h);

				__m256i squaredl = _mm256_mullo_epi32(diffl, diffl);
				__m256i squaredh = _mm256_mullo_epi32(diffh, diffh);

				error8 = _mm256_add_epi32(error8, squaredl);
				error8 = _mm256_add_epi32(error8, squaredh);
			}
			__m256i error4 = _mm256_hadd_epi32(error8, zero);
			__m256i error2 = _mm256_hadd_epi32(error4, zero); //error2 has 2 partial sums in 0 and 4
			__m128i error2l = _mm256_extracti128_si256(error2, 0);
			__m128i error2h = _mm256_extracti128_si256(error2, 1);
			__m128i error1 = _mm_add_epi32(error2l, error2h);

			int error = _mm_cvtsi128_si32(error1);
			//5739837, 7025841, 5795133, 6536253, 5500006
			//6093159, 5652340, 6993727, 4700000, 5134448
			if (error < bestError)
			{
				bestError = error;
				bestLabel = trainLabels[8 + j];
			}
		}
		if (bestLabel != label)
		{
			//115, 195, 241, 268, 300
			miss++;
		}
	}
	printf("%i misses for accuracy: %f\n", miss, (float)(testCount - miss) / (float)testCount);
}

//Compared to Opt1 his version is about 5-10% faster in 64bit, and 1-2% slower in 32 bit, need the
//extra registers in 64 bit
void TestBestMatchOpt2()
{
	std::vector<unsigned char>	testImages = LoadFile("t10k-images.idx3-ubyte");
	std::vector<unsigned char>	testLabels = LoadFile("t10k-labels.idx1-ubyte");
	std::vector<unsigned char>	trainImages = LoadFile("train-images.idx3-ubyte");
	std::vector<unsigned char>	trainLabels = LoadFile("train-labels.idx1-ubyte");

	int trainCount = BigLong(trainImages, 4);
	int testCount = BigLong(testImages, 4) >> 5;	// shrink for faster tests

	__m128i shuffle = _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);

	int	miss = 0;
	for (int i = 0; i < testCount; i++)
	{
		unsigned char label = testLabels[8 + i];
		assert(label >= 0 && label <= 9);
		const unsigned char * testData = &testImages[16 + i*NumDimensions];

		int bestLabel = -1;
		int bestError = INT_MAX;
		__m256i zero = _mm256_setzero_si256();
		for (int j = 0; j < trainCount; j++)
		{
			const unsigned char * trainData = &trainImages[16 + j*NumDimensions];
			__m256i error8l_0 = _mm256_setzero_si256();
			__m256i error8h_0 = _mm256_setzero_si256();
			__m256i error8l_1 = _mm256_setzero_si256();
			__m256i error8h_1 = _mm256_setzero_si256();

			for (int k = 0; k < NumDimensions; k += 32)
			{
				__m128i test8_0 = _mm_load_si128((const __m128i*)(testData + k));
				__m128i train8_0 = _mm_load_si128((const __m128i*)(trainData + k));
				__m128i test8_1 = _mm_load_si128((const __m128i*)(testData + k+16));
				__m128i train8_1 = _mm_load_si128((const __m128i*)(trainData + k+16));

				__m256i test32l_0 = _mm256_cvtepu8_epi32(test8_0);
				__m256i train32l_0 = _mm256_cvtepu8_epi32(train8_0);
				__m256i test32l_1 = _mm256_cvtepu8_epi32(test8_1);
				__m256i train32l_1 = _mm256_cvtepu8_epi32(train8_1);

				test8_0 = _mm_shuffle_epi8(test8_0, shuffle);
				train8_0 = _mm_shuffle_epi8(train8_0, shuffle);
				test8_1 = _mm_shuffle_epi8(test8_1, shuffle);
				train8_1 = _mm_shuffle_epi8(train8_1, shuffle);

				__m256i test32h_0 = _mm256_cvtepu8_epi32(test8_0);
				__m256i train32h_0 = _mm256_cvtepu8_epi32(train8_0);
				__m256i test32h_1 = _mm256_cvtepu8_epi32(test8_1);
				__m256i train32h_1 = _mm256_cvtepu8_epi32(train8_1);

				__m256i diffl_0 = _mm256_sub_epi32(test32l_0, train32l_0);
				__m256i diffh_0 = _mm256_sub_epi32(test32h_0, train32h_0);
				__m256i diffl_1 = _mm256_sub_epi32(test32l_1, train32l_1);
				__m256i diffh_1 = _mm256_sub_epi32(test32h_1, train32h_1);

				__m256i squaredl_0 = _mm256_mullo_epi32(diffl_0, diffl_0);
				__m256i squaredh_0 = _mm256_mullo_epi32(diffh_0, diffh_0);
				__m256i squaredl_1 = _mm256_mullo_epi32(diffl_1, diffl_1);
				__m256i squaredh_1 = _mm256_mullo_epi32(diffh_1, diffh_1);

				error8l_0 = _mm256_add_epi32(error8l_0, squaredl_0);
				error8h_0 = _mm256_add_epi32(error8h_0, squaredh_0);
				error8l_1 = _mm256_add_epi32(error8l_1, squaredl_1);
				error8h_1 = _mm256_add_epi32(error8h_1, squaredh_1);
			}
			__m256i error8 = _mm256_add_epi32(error8l_0, error8h_0);
			error8 = _mm256_add_epi32(error8, error8l_1);
			error8 = _mm256_add_epi32(error8, error8h_1);

			__m256i error4 = _mm256_hadd_epi32(error8, zero);
			__m256i error2 = _mm256_hadd_epi32(error4, zero); //error2 has 2 partial sums in 0 and 4
			__m128i error2l = _mm256_extracti128_si256(error2, 0);
			__m128i error2h = _mm256_extracti128_si256(error2, 1);
			__m128i error1 = _mm_add_epi32(error2l, error2h);

			int error = _mm_cvtsi128_si32(error1);
			//5739837, 7025841, 5795133, 6536253, 5500006
			//6093159, 5652340, 6993727, 4700000, 5134448
			if (error < bestError)
			{
				bestError = error;
				bestLabel = trainLabels[8 + j];
			}
		}
		if (bestLabel != label)
		{
			//115, 195, 241, 268, 300
			miss++;
		}
	}
	printf("%i misses for accuracy: %f\n", miss, (float)(testCount - miss) / (float)testCount);
}

int main(int argc, char ** argv)
{
	std::chrono::time_point<std::chrono::system_clock> start, end;

	start = std::chrono::system_clock::now();
	TestBestMatch();
	end = std::chrono::system_clock::now();
	std::chrono::duration<double> elapsed_seconds = end - start;
	printf("%f seconds\n", elapsed_seconds.count());

	start = std::chrono::system_clock::now();
	TestBestMatchOpt1();
	end = std::chrono::system_clock::now();
	elapsed_seconds = end - start;
	printf("%f seconds\n", elapsed_seconds.count());

	start = std::chrono::system_clock::now();
	TestBestMatchOpt2();
	end = std::chrono::system_clock::now();
	elapsed_seconds = end - start;
	printf("%f seconds\n", elapsed_seconds.count());
}<|endoftext|>


<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "Layer.h"
#include "core/Engine.h"
#include "Node.h"
#include "Camera.h"
#include "graphics/Renderer.h"
#include "Scene.h"
#include "math/Matrix4.h"
#include "Component.h"

namespace ouzel
{
    namespace scene
    {
        Layer::Layer()
        {
        }

        Layer::~Layer()
        {
            for (Camera* camera : cameras)
            {
                camera->layer = nullptr;
            }

            if (scene) scene->removeLayer(this);
        }

        void Layer::draw()
        {
            for (Camera* camera : cameras)
            {
                std::vector<Node*> drawQueue;

                for (Node* child : children)
                {
                    if (!child->isHidden())
                    {
                        child->visit(drawQueue, Matrix4::IDENTITY, false, camera, 0.0f);
                    }
                }

                for (Node* node : drawQueue)
                {
                    node->draw(camera);

                    if (camera->getWireframe())
                    {
                        node->drawWireframe(camera);
                    }
                }
            }
        }

        void Layer::addChild(Node* node)
        {
            NodeContainer::addChild(node);
            node->updateTransform(Matrix4::IDENTITY);
        }

        void Layer::addCamera(Camera* camera)
        {
            Layer* oldLayer = camera->layer;

            if (oldLayer)
            {
                oldLayer->removeCamera(camera);
            }

            cameras.push_back(camera);
            camera->layer = this;
            if (!camera->parent) camera->updateTransform(Matrix4::IDENTITY);
            camera->recalculateProjection();
        }

        void Layer::removeCamera(Camera* camera)
        {
            auto i = std::find(cameras.begin(), cameras.end(), camera);

            if (i != cameras.end())
            {
                camera->layer = nullptr;
                cameras.erase(i);
            }
        }

        Node* Layer::pickNode(const Vector2& position) const
        {
            for (auto i = cameras.rbegin(); i != cameras.rend(); ++i)
            {
                Camera* camera = *i;

                std::vector<Node*> nodes;

                Vector2 worldPosition = camera->convertNormalizedToWorld(position);

                findNodes(worldPosition, nodes);

                if (!nodes.empty()) return nodes.front();
            }

            return nullptr;
        }

        std::vector<Node*> Layer::pickNodes(const Vector2& position) const
        {
            std::vector<Node*> result;

            for (auto i = cameras.rbegin(); i != cameras.rend(); ++i)
            {
                Camera* camera = *i;

                Vector2 worldPosition = camera->convertNormalizedToWorld(position);

                std::vector<Node*> nodes;
                findNodes(worldPosition, nodes);

                result.insert(result.end(), nodes.begin(), nodes.end());
            }

            return result;
        }

        std::vector<Node*> Layer::pickNodes(const std::vector<Vector2>& edges) const
        {
            std::vector<Node*> result;

            for (auto i = cameras.rbegin(); i != cameras.rend(); ++i)
            {
                Camera* camera = *i;

                std::vector<Vector2> worldEdges;
                worldEdges.reserve(edges.size());

                for (const Vector2& edge : edges)
                {
                    worldEdges.push_back(camera->convertNormalizedToWorld(edge));
                }

                std::vector<Node*> nodes;
                findNodes(worldEdges, nodes);

                result.insert(result.end(), nodes.begin(), nodes.end());
            }

            return result;
        }

        void Layer::setOrder(int32_t newOrder)
        {
            order = newOrder;
        }

        void Layer::recalculateProjection()
        {
            for (Camera* camera : cameras)
            {
                camera->recalculateProjection();
            }
        }

        void Layer::enter()
        {
            NodeContainer::enter();

            recalculateProjection();
        }
    } // namespace scene
} // namespace ouzel
<commit_msg>Pass int literal to Node::visit<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "Layer.h"
#include "core/Engine.h"
#include "Node.h"
#include "Camera.h"
#include "graphics/Renderer.h"
#include "Scene.h"
#include "math/Matrix4.h"
#include "Component.h"

namespace ouzel
{
    namespace scene
    {
        Layer::Layer()
        {
        }

        Layer::~Layer()
        {
            for (Camera* camera : cameras)
            {
                camera->layer = nullptr;
            }

            if (scene) scene->removeLayer(this);
        }

        void Layer::draw()
        {
            for (Camera* camera : cameras)
            {
                std::vector<Node*> drawQueue;

                for (Node* child : children)
                {
                    if (!child->isHidden())
                    {
                        child->visit(drawQueue, Matrix4::IDENTITY, false, camera, 0);
                    }
                }

                for (Node* node : drawQueue)
                {
                    node->draw(camera);

                    if (camera->getWireframe())
                    {
                        node->drawWireframe(camera);
                    }
                }
            }
        }

        void Layer::addChild(Node* node)
        {
            NodeContainer::addChild(node);
            node->updateTransform(Matrix4::IDENTITY);
        }

        void Layer::addCamera(Camera* camera)
        {
            Layer* oldLayer = camera->layer;

            if (oldLayer)
            {
                oldLayer->removeCamera(camera);
            }

            cameras.push_back(camera);
            camera->layer = this;
            if (!camera->parent) camera->updateTransform(Matrix4::IDENTITY);
            camera->recalculateProjection();
        }

        void Layer::removeCamera(Camera* camera)
        {
            auto i = std::find(cameras.begin(), cameras.end(), camera);

            if (i != cameras.end())
            {
                camera->layer = nullptr;
                cameras.erase(i);
            }
        }

        Node* Layer::pickNode(const Vector2& position) const
        {
            for (auto i = cameras.rbegin(); i != cameras.rend(); ++i)
            {
                Camera* camera = *i;

                std::vector<Node*> nodes;

                Vector2 worldPosition = camera->convertNormalizedToWorld(position);

                findNodes(worldPosition, nodes);

                if (!nodes.empty()) return nodes.front();
            }

            return nullptr;
        }

        std::vector<Node*> Layer::pickNodes(const Vector2& position) const
        {
            std::vector<Node*> result;

            for (auto i = cameras.rbegin(); i != cameras.rend(); ++i)
            {
                Camera* camera = *i;

                Vector2 worldPosition = camera->convertNormalizedToWorld(position);

                std::vector<Node*> nodes;
                findNodes(worldPosition, nodes);

                result.insert(result.end(), nodes.begin(), nodes.end());
            }

            return result;
        }

        std::vector<Node*> Layer::pickNodes(const std::vector<Vector2>& edges) const
        {
            std::vector<Node*> result;

            for (auto i = cameras.rbegin(); i != cameras.rend(); ++i)
            {
                Camera* camera = *i;

                std::vector<Vector2> worldEdges;
                worldEdges.reserve(edges.size());

                for (const Vector2& edge : edges)
                {
                    worldEdges.push_back(camera->convertNormalizedToWorld(edge));
                }

                std::vector<Node*> nodes;
                findNodes(worldEdges, nodes);

                result.insert(result.end(), nodes.begin(), nodes.end());
            }

            return result;
        }

        void Layer::setOrder(int32_t newOrder)
        {
            order = newOrder;
        }

        void Layer::recalculateProjection()
        {
            for (Camera* camera : cameras)
            {
                camera->recalculateProjection();
            }
        }

        void Layer::enter()
        {
            NodeContainer::enter();

            recalculateProjection();
        }
    } // namespace scene
} // namespace ouzel
<|endoftext|>


<commit_before>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ClientData/ProcessData.h"

#include <absl/container/flat_hash_map.h>

#include <cstdint>
#include <vector>

#include "GrpcProtos/symbol.pb.h"
#include "OrbitBase/Result.h"
#include "absl/strings/str_format.h"

using orbit_grpc_protos::ModuleInfo;

namespace orbit_client_data {

ProcessData::ProcessData() { process_info_.set_pid(-1); }

void ProcessData::SetProcessInfo(const orbit_grpc_protos::ProcessInfo& process_info) {
  absl::MutexLock lock(&mutex_);
  process_info_ = process_info;
}

uint32_t ProcessData::pid() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.pid();
}

const std::string& ProcessData::name() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.name();
}

double ProcessData::cpu_usage() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.cpu_usage();
}

const std::string& ProcessData::full_path() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.full_path();
}

const std::string& ProcessData::command_line() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.command_line();
}

bool ProcessData::is_64_bit() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.is_64_bit();
}

const std::string& ProcessData::build_id() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.build_id();
}

[[maybe_unused]] static bool IsModuleMapValid(
    const std::map<uint64_t, ModuleInMemory>& module_map) {
  // Check that modules do not intersect in the address space.
  uint64_t last_end_address = 0;
  for (const auto& [unused_address, module_in_memory] : module_map) {
    if (module_in_memory.start() < last_end_address) return false;
    last_end_address = module_in_memory.end();
  }

  return true;
}

void ProcessData::UpdateModuleInfos(absl::Span<const ModuleInfo> module_infos) {
  absl::MutexLock lock(&mutex_);
  start_address_to_module_in_memory_.clear();

  for (const auto& module_info : module_infos) {
    const auto [unused_it, success] = start_address_to_module_in_memory_.try_emplace(
        module_info.address_start(), module_info.address_start(), module_info.address_end(),
        module_info.file_path(), module_info.build_id());
    ORBIT_CHECK(success);
  }

  // Files saved with Orbit 1.65 may have intersecting maps, this is why we use DCHECK here
  // instead of CHECK
  ORBIT_DCHECK(IsModuleMapValid(start_address_to_module_in_memory_));
}

std::vector<std::string> ProcessData::FindModuleBuildIdsByPath(
    const std::string& module_path) const {
  absl::MutexLock lock(&mutex_);
  std::set<std::string> build_ids;

  for (const auto& [unused_address, module_in_memory] : start_address_to_module_in_memory_) {
    if (module_in_memory.file_path() == module_path) {
      build_ids.insert(module_in_memory.build_id());
    }
  }

  return {build_ids.begin(), build_ids.end()};
}

void ProcessData::AddOrUpdateModuleInfo(const ModuleInfo& module_info) {
  absl::MutexLock lock(&mutex_);
  ModuleInMemory module_in_memory{module_info.address_start(), module_info.address_end(),
                                  module_info.file_path(), module_info.build_id()};

  auto it = start_address_to_module_in_memory_.upper_bound(module_in_memory.start());
  if (it != start_address_to_module_in_memory_.begin()) {
    --it;
    if (it->second.end() > module_in_memory.start()) {
      it = start_address_to_module_in_memory_.erase(it);
    } else {
      ++it;
    }
  }

  while (it != start_address_to_module_in_memory_.end() &&
         it->second.start() < module_in_memory.end()) {
    it = start_address_to_module_in_memory_.erase(it);
  }

  start_address_to_module_in_memory_.insert_or_assign(module_info.address_start(),
                                                      module_in_memory);

  ORBIT_CHECK(IsModuleMapValid(start_address_to_module_in_memory_));
}

ErrorMessageOr<ModuleInMemory> ProcessData::FindModuleByAddress(uint64_t absolute_address) const {
  absl::MutexLock lock(&mutex_);
  if (start_address_to_module_in_memory_.empty()) {
    return ErrorMessage(
        absl::StrFormat("Unable to find module for address %016x: No modules loaded by process %s",
                        absolute_address, process_info_.name()));
  }

  ErrorMessage not_found_error = ErrorMessage(absl::StrFormat(
      "Unable to find module for address %016x: No module loaded at this address by process %s",
      absolute_address, process_info_.name()));

  auto it = start_address_to_module_in_memory_.upper_bound(absolute_address);
  if (it == start_address_to_module_in_memory_.begin()) return not_found_error;

  --it;
  const ModuleInMemory& module_in_memory = it->second;
  ORBIT_CHECK(absolute_address >= module_in_memory.start());
  if (absolute_address >= module_in_memory.end()) return not_found_error;

  return module_in_memory;
}

std::vector<uint64_t> ProcessData::GetModuleBaseAddresses(const std::string& module_path,
                                                          const std::string& build_id) const {
  absl::MutexLock lock(&mutex_);
  std::vector<uint64_t> result;
  for (const auto& [start_address, module_in_memory] : start_address_to_module_in_memory_) {
    if (module_in_memory.file_path() == module_path && module_in_memory.build_id() == build_id) {
      result.emplace_back(start_address);
    }
  }
  return result;
}

std::map<uint64_t, ModuleInMemory> ProcessData::GetMemoryMapCopy() const {
  absl::MutexLock lock(&mutex_);
  return start_address_to_module_in_memory_;
}

bool ProcessData::IsModuleLoadedByProcess(const ModuleData* module) const {
  absl::MutexLock lock(&mutex_);
  return std::any_of(start_address_to_module_in_memory_.begin(),
                     start_address_to_module_in_memory_.end(), [module](const auto& it) {
                       return it.second.file_path() == module->file_path() &&
                              it.second.build_id() == module->build_id();
                     });
}

std::vector<std::pair<std::string, std::string>> ProcessData::GetUniqueModulesPathAndBuildId()
    const {
  absl::MutexLock lock(&mutex_);
  std::set<std::pair<std::string, std::string>> module_keys;
  for (const auto& [unused_address, module_in_memory] : start_address_to_module_in_memory_) {
    module_keys.insert(std::make_pair(module_in_memory.file_path(), module_in_memory.build_id()));
  }

  return {module_keys.begin(), module_keys.end()};
}

}  // namespace orbit_client_data
<commit_msg>Don't always create ErrorMessage in ProcessData::FindModuleByAddress (#3276)<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ClientData/ProcessData.h"

#include <absl/container/flat_hash_map.h>

#include <cstdint>
#include <vector>

#include "GrpcProtos/symbol.pb.h"
#include "OrbitBase/Result.h"
#include "absl/strings/str_format.h"

using orbit_grpc_protos::ModuleInfo;

namespace orbit_client_data {

ProcessData::ProcessData() { process_info_.set_pid(-1); }

void ProcessData::SetProcessInfo(const orbit_grpc_protos::ProcessInfo& process_info) {
  absl::MutexLock lock(&mutex_);
  process_info_ = process_info;
}

uint32_t ProcessData::pid() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.pid();
}

const std::string& ProcessData::name() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.name();
}

double ProcessData::cpu_usage() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.cpu_usage();
}

const std::string& ProcessData::full_path() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.full_path();
}

const std::string& ProcessData::command_line() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.command_line();
}

bool ProcessData::is_64_bit() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.is_64_bit();
}

const std::string& ProcessData::build_id() const {
  absl::MutexLock lock(&mutex_);
  return process_info_.build_id();
}

[[maybe_unused]] static bool IsModuleMapValid(
    const std::map<uint64_t, ModuleInMemory>& module_map) {
  // Check that modules do not intersect in the address space.
  uint64_t last_end_address = 0;
  for (const auto& [unused_address, module_in_memory] : module_map) {
    if (module_in_memory.start() < last_end_address) return false;
    last_end_address = module_in_memory.end();
  }

  return true;
}

void ProcessData::UpdateModuleInfos(absl::Span<const ModuleInfo> module_infos) {
  absl::MutexLock lock(&mutex_);
  start_address_to_module_in_memory_.clear();

  for (const auto& module_info : module_infos) {
    const auto [unused_it, success] = start_address_to_module_in_memory_.try_emplace(
        module_info.address_start(), module_info.address_start(), module_info.address_end(),
        module_info.file_path(), module_info.build_id());
    ORBIT_CHECK(success);
  }

  // Files saved with Orbit 1.65 may have intersecting maps, this is why we use DCHECK here
  // instead of CHECK
  ORBIT_DCHECK(IsModuleMapValid(start_address_to_module_in_memory_));
}

std::vector<std::string> ProcessData::FindModuleBuildIdsByPath(
    const std::string& module_path) const {
  absl::MutexLock lock(&mutex_);
  std::set<std::string> build_ids;

  for (const auto& [unused_address, module_in_memory] : start_address_to_module_in_memory_) {
    if (module_in_memory.file_path() == module_path) {
      build_ids.insert(module_in_memory.build_id());
    }
  }

  return {build_ids.begin(), build_ids.end()};
}

void ProcessData::AddOrUpdateModuleInfo(const ModuleInfo& module_info) {
  absl::MutexLock lock(&mutex_);
  ModuleInMemory module_in_memory{module_info.address_start(), module_info.address_end(),
                                  module_info.file_path(), module_info.build_id()};

  auto it = start_address_to_module_in_memory_.upper_bound(module_in_memory.start());
  if (it != start_address_to_module_in_memory_.begin()) {
    --it;
    if (it->second.end() > module_in_memory.start()) {
      it = start_address_to_module_in_memory_.erase(it);
    } else {
      ++it;
    }
  }

  while (it != start_address_to_module_in_memory_.end() &&
         it->second.start() < module_in_memory.end()) {
    it = start_address_to_module_in_memory_.erase(it);
  }

  start_address_to_module_in_memory_.insert_or_assign(module_info.address_start(),
                                                      module_in_memory);

  ORBIT_CHECK(IsModuleMapValid(start_address_to_module_in_memory_));
}

ErrorMessageOr<ModuleInMemory> ProcessData::FindModuleByAddress(uint64_t absolute_address) const {
  absl::MutexLock lock(&mutex_);
  if (start_address_to_module_in_memory_.empty()) {
    return ErrorMessage(
        absl::StrFormat("Unable to find module for address %016x: No modules loaded by process %s",
                        absolute_address, process_info_.name()));
  }

  static constexpr const char* kNotFoundErrorFormat{
      "Unable to find module for address %016x: No module loaded at this address by process %s"};

  auto it = start_address_to_module_in_memory_.upper_bound(absolute_address);
  if (it == start_address_to_module_in_memory_.begin()) {
    return ErrorMessage{
        absl::StrFormat(kNotFoundErrorFormat, absolute_address, process_info_.name())};
  }

  --it;
  const ModuleInMemory& module_in_memory = it->second;
  ORBIT_CHECK(absolute_address >= module_in_memory.start());
  if (absolute_address >= module_in_memory.end()) {
    return ErrorMessage{
        absl::StrFormat(kNotFoundErrorFormat, absolute_address, process_info_.name())};
  }

  return module_in_memory;
}

std::vector<uint64_t> ProcessData::GetModuleBaseAddresses(const std::string& module_path,
                                                          const std::string& build_id) const {
  absl::MutexLock lock(&mutex_);
  std::vector<uint64_t> result;
  for (const auto& [start_address, module_in_memory] : start_address_to_module_in_memory_) {
    if (module_in_memory.file_path() == module_path && module_in_memory.build_id() == build_id) {
      result.emplace_back(start_address);
    }
  }
  return result;
}

std::map<uint64_t, ModuleInMemory> ProcessData::GetMemoryMapCopy() const {
  absl::MutexLock lock(&mutex_);
  return start_address_to_module_in_memory_;
}

bool ProcessData::IsModuleLoadedByProcess(const ModuleData* module) const {
  absl::MutexLock lock(&mutex_);
  return std::any_of(start_address_to_module_in_memory_.begin(),
                     start_address_to_module_in_memory_.end(), [module](const auto& it) {
                       return it.second.file_path() == module->file_path() &&
                              it.second.build_id() == module->build_id();
                     });
}

std::vector<std::pair<std::string, std::string>> ProcessData::GetUniqueModulesPathAndBuildId()
    const {
  absl::MutexLock lock(&mutex_);
  std::set<std::pair<std::string, std::string>> module_keys;
  for (const auto& [unused_address, module_in_memory] : start_address_to_module_in_memory_) {
    module_keys.insert(std::make_pair(module_in_memory.file_path(), module_in_memory.build_id()));
  }

  return {module_keys.begin(), module_keys.end()};
}

}  // namespace orbit_client_data
<|endoftext|>