<commit_before>/* This file is part of the KDE project
   Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
   Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
   Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
   Copyright (C) 2007 Mirko Stocker <me@misto.ch>
   Copyright (C) 2009 Dominik Haumann <dhaumann kde org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

//BEGIN Includes
#include "katefilebrowser.h"
#include "katefilebrowser.moc"

#include "katebookmarkhandler.h"

#include <ktexteditor/document.h>
#include <ktexteditor/view.h>

#include <KActionCollection>
#include <KActionMenu>
#include <KConfigGroup>
#include <KDebug>
#include <KDirOperator>
#include <KFilePlacesModel>
#include <KHistoryComboBox>
#include <KLocale>
#include <KToolBar>
#include <KUrlNavigator>
#include <QAbstractItemView>
#include <QDir>
#include <QLabel>
#include <QLineEdit>
#include <QToolButton>
//END Includes

KateFileBrowser::KateFileBrowser(Kate::MainWindow *mainWindow,
                                 QWidget * parent, const char * name)
  : KVBox (parent)
  , m_mainWindow(mainWindow)
{
  setObjectName(name);

  m_toolbar = new KToolBar(this);
  m_toolbar->setMovable(false);
  m_toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
  m_toolbar->setContextMenuPolicy(Qt::NoContextMenu);

  // includes some actions, but not hooked into the shortcut dialog atm
  m_actionCollection = new KActionCollection(this);
  m_actionCollection->addAssociatedWidget(this);

  KFilePlacesModel* model = new KFilePlacesModel(this);
  m_urlNavigator = new KUrlNavigator(model, KUrl(QDir::homePath()), this);
  connect(m_urlNavigator, SIGNAL(urlChanged(const KUrl&)), SLOT(updateDirOperator(const KUrl&)));

  m_dirOperator = new KDirOperator(KUrl(), this);
  m_dirOperator->setView(KFile::/* Simple */Detail);
  m_dirOperator->view()->setSelectionMode(QAbstractItemView::ExtendedSelection);
  connect(m_dirOperator, SIGNAL(viewChanged(QAbstractItemView *)),
          this, SLOT(selectorViewChanged(QAbstractItemView *)));
  m_dirOperator->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
  setFocusProxy(m_dirOperator);

  // now all actions exist in dir operator and we can use them in the toolbar
  setupToolbar();

  KHBox* filterBox = new KHBox(this);

  QLabel* filterLabel = new QLabel(i18n("Filter:"), filterBox);
  m_filter = new KHistoryComboBox(true, filterBox);
  filterLabel->setBuddy(m_filter);
  m_filter->setMaxCount(10);
  m_filter->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));

  connect(m_filter, SIGNAL(editTextChanged(const QString&)),
          SLOT(slotFilterChange(const QString&)));
  connect(m_filter, SIGNAL(returnPressed(const QString&)),
          m_filter, SLOT(addToHistory(const QString&)));
  connect(m_filter, SIGNAL(returnPressed(const QString&)),
          m_dirOperator, SLOT(setFocus()));

  connect(m_dirOperator, SIGNAL(urlEntered(const KUrl&)),
          this, SLOT(updateUrlNavigator(const KUrl&)));

  // Connect the bookmark handler
  connect(m_bookmarkHandler, SIGNAL(openUrl(const QString&)),
          this, SLOT(setDir(const QString&)));

  m_filter->setWhatsThis(i18n("Enter a name filter to limit which files are displayed."));

  connect(m_dirOperator, SIGNAL(fileSelected(const KFileItem&)), this, SLOT(fileSelected(const KFileItem&)));
  connect(m_mainWindow, SIGNAL(viewChanged()), this, SLOT(autoSyncFolder()));
}

KateFileBrowser::~KateFileBrowser()
{
}
//END Constroctor/Destrctor

//BEGIN Public Methods
void KateFileBrowser::setupToolbar()
{
  // remove all actions from the toolbar (there should be none)
  m_toolbar->clear();

  // create action list
  QList<QAction*> actions;
  actions << m_dirOperator->actionCollection()->action("back");
  actions << m_dirOperator->actionCollection()->action("forward");

  // bookmarks action!
  KActionMenu *acmBookmarks = new KActionMenu(KIcon("bookmarks"), i18n("Bookmarks"), this);
  acmBookmarks->setDelayed(false);
  m_bookmarkHandler = new KateBookmarkHandler(this, acmBookmarks->menu());
  acmBookmarks->setShortcutContext(Qt::WidgetWithChildrenShortcut);
  actions << acmBookmarks;

  // action for synchronising the dir operator with the current document path
  KAction* syncFolder = new KAction(this);
  syncFolder->setShortcutContext(Qt::WidgetWithChildrenShortcut);
  syncFolder->setText(i18n("Current Document Folder"));
  syncFolder->setIcon(KIcon("system-switch-user"));
  connect(syncFolder, SIGNAL(triggered()), this, SLOT(setActiveDocumentDir()));

  actions << syncFolder;

  // now add all actions to the toolbar
  foreach (QAction* ac, actions) {
    if (ac) {
      m_toolbar->addAction(ac);
    }
  }

  m_actionCollection->addAction("sync_dir", syncFolder);
  m_actionCollection->addAction("bookmarks", acmBookmarks);

  // section for settings menu
  KActionMenu *optionsMenu = new KActionMenu(KIcon("configure"), i18n("Options"), this);
  optionsMenu->setDelayed(false);
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("short view"));
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("detailed view"));
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("tree view"));
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("detailed tree view"));
  optionsMenu->addSeparator();
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("show hidden"));

  // action for synchronising the dir operator with the current document path
  m_autoSyncFolder = new KAction(this);
  m_autoSyncFolder->setCheckable(true);
  m_autoSyncFolder->setText(i18n("Automatically synchronize with current document"));
  m_autoSyncFolder->setIcon(KIcon("system-switch-user"));
  connect(m_autoSyncFolder, SIGNAL(triggered()), this, SLOT(autoSyncFolder()));
  optionsMenu->addAction(m_autoSyncFolder);

  m_toolbar->addSeparator();
  m_toolbar->addAction(optionsMenu);
}

void KateFileBrowser::readSessionConfig(KConfigBase *config, const QString & name)
{
  KConfigGroup cgDir(config, name + ":dir");
  m_dirOperator->readConfig(cgDir);
  m_dirOperator->setView(KFile::Default);

  KConfigGroup cg(config, name);
  m_urlNavigator->setUrl(cg.readPathEntry("location", QDir::homePath()));
  setDir(cg.readPathEntry("location", QDir::homePath()));
  m_autoSyncFolder->setChecked(cg.readEntry("auto sync folder", false));
  m_filter->setHistoryItems(cg.readEntry("filter history", QStringList()), true);
}

void KateFileBrowser::writeSessionConfig(KConfigBase *config, const QString & name)
{
  KConfigGroup cgDir(config, name + ":dir");
  m_dirOperator->writeConfig(cgDir);

  KConfigGroup cg = KConfigGroup(config, name);
  cg.writePathEntry("location", m_urlNavigator->url().url());
  cg.writeEntry("auto sync folder", m_autoSyncFolder->isChecked());
  cg.writeEntry("filter history", m_filter->historyItems());
}

//END Public Methods

//BEGIN Public Slots

void KateFileBrowser::slotFilterChange(const QString & nf)
{
  QString f = '*' + nf.trimmed() + '*';
  const bool empty = f.isEmpty() || f == "*" || f == "**" || f == "***";

  if (empty) {
    m_dirOperator->clearFilter();
    m_filter->lineEdit()->clear();
  } else {
    m_dirOperator->setNameFilter(f);
  }

  m_dirOperator->updateDir();
}

bool kateFileSelectorIsReadable (const KUrl& url)
{
  if (!url.isLocalFile())
    return true; // what else can we say?

  QDir dir(url.toLocalFile());
  return dir.exists ();
}

void KateFileBrowser::setDir(KUrl u)
{
  KUrl newurl;

  if (!u.isValid())
    newurl.setPath(QDir::homePath());
  else
    newurl = u;

  QString pathstr = newurl.path(KUrl::AddTrailingSlash);
  newurl.setPath(pathstr);

  if (!kateFileSelectorIsReadable (newurl))
    newurl.cd(QString::fromLatin1(".."));

  if (!kateFileSelectorIsReadable (newurl))
    newurl.setPath(QDir::homePath());

  m_dirOperator->setUrl(newurl, true);
}

//END Public Slots

//BEGIN Private Slots

void KateFileBrowser::fileSelected(const KFileItem & /*file*/)
{
  openSelectedFiles();
}

void KateFileBrowser::openSelectedFiles()
{
  const KFileItemList list = m_dirOperator->selectedItems();

  foreach (const KFileItem& item, list)
  {
    m_mainWindow->openUrl(item.url());
  }

  m_dirOperator->view()->selectionModel()->clear();
}

void KateFileBrowser::updateDirOperator(const KUrl& u)
{
  m_dirOperator->setUrl(u, true);
}

void KateFileBrowser::updateUrlNavigator(const KUrl& u)
{
  m_urlNavigator->setUrl(u);
}

void KateFileBrowser::setActiveDocumentDir()
{
//   kDebug(13001)<<"KateFileBrowser::setActiveDocumentDir()";
  KUrl u = activeDocumentUrl();
//   kDebug(13001)<<"URL: "<<u.prettyUrl();
  if (!u.isEmpty())
    setDir(u.upUrl());
//   kDebug(13001)<<"... setActiveDocumentDir() DONE!";
}

void KateFileBrowser::autoSyncFolder()
{
  if (m_autoSyncFolder->isChecked()) {
    setActiveDocumentDir();
  }
}

void KateFileBrowser::selectorViewChanged(QAbstractItemView * newView)
{
  newView->setSelectionMode(QAbstractItemView::ExtendedSelection);
}

//END Private Slots

//BEGIN Protected

KUrl KateFileBrowser::activeDocumentUrl()
{
  KTextEditor::View *v = m_mainWindow->activeView();
  if (v)
    return v->document()->url();
  return KUrl();
}
//END Protected

// kate: space-indent on; indent-width 2; replace-tabs on;
<commit_msg>focus diroperator after chaing url in navigator<commit_after>/* This file is part of the KDE project
   Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
   Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
   Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
   Copyright (C) 2007 Mirko Stocker <me@misto.ch>
   Copyright (C) 2009 Dominik Haumann <dhaumann kde org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

//BEGIN Includes
#include "katefilebrowser.h"
#include "katefilebrowser.moc"

#include "katebookmarkhandler.h"

#include <ktexteditor/document.h>
#include <ktexteditor/view.h>

#include <KActionCollection>
#include <KActionMenu>
#include <KConfigGroup>
#include <KDebug>
#include <KDirOperator>
#include <KFilePlacesModel>
#include <KHistoryComboBox>
#include <KLocale>
#include <KToolBar>
#include <KUrlNavigator>
#include <QAbstractItemView>
#include <QDir>
#include <QLabel>
#include <QLineEdit>
#include <QToolButton>
//END Includes

KateFileBrowser::KateFileBrowser(Kate::MainWindow *mainWindow,
                                 QWidget * parent, const char * name)
  : KVBox (parent)
  , m_mainWindow(mainWindow)
{
  setObjectName(name);

  m_toolbar = new KToolBar(this);
  m_toolbar->setMovable(false);
  m_toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
  m_toolbar->setContextMenuPolicy(Qt::NoContextMenu);

  // includes some actions, but not hooked into the shortcut dialog atm
  m_actionCollection = new KActionCollection(this);
  m_actionCollection->addAssociatedWidget(this);

  KFilePlacesModel* model = new KFilePlacesModel(this);
  m_urlNavigator = new KUrlNavigator(model, KUrl(QDir::homePath()), this);
  connect(m_urlNavigator, SIGNAL(urlChanged(const KUrl&)), SLOT(updateDirOperator(const KUrl&)));

  m_dirOperator = new KDirOperator(KUrl(), this);
  m_dirOperator->setView(KFile::/* Simple */Detail);
  m_dirOperator->view()->setSelectionMode(QAbstractItemView::ExtendedSelection);
  connect(m_dirOperator, SIGNAL(viewChanged(QAbstractItemView *)),
          this, SLOT(selectorViewChanged(QAbstractItemView *)));
  m_dirOperator->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
  setFocusProxy(m_dirOperator);

  // now all actions exist in dir operator and we can use them in the toolbar
  setupToolbar();

  KHBox* filterBox = new KHBox(this);

  QLabel* filterLabel = new QLabel(i18n("Filter:"), filterBox);
  m_filter = new KHistoryComboBox(true, filterBox);
  filterLabel->setBuddy(m_filter);
  m_filter->setMaxCount(10);
  m_filter->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));

  connect(m_filter, SIGNAL(editTextChanged(const QString&)),
          SLOT(slotFilterChange(const QString&)));
  connect(m_filter, SIGNAL(returnPressed(const QString&)),
          m_filter, SLOT(addToHistory(const QString&)));
  connect(m_filter, SIGNAL(returnPressed(const QString&)),
          m_dirOperator, SLOT(setFocus()));

  connect(m_dirOperator, SIGNAL(urlEntered(const KUrl&)),
          this, SLOT(updateUrlNavigator(const KUrl&)));

  // Connect the bookmark handler
  connect(m_bookmarkHandler, SIGNAL(openUrl(const QString&)),
          this, SLOT(setDir(const QString&)));

  m_filter->setWhatsThis(i18n("Enter a name filter to limit which files are displayed."));

  connect(m_dirOperator, SIGNAL(fileSelected(const KFileItem&)), this, SLOT(fileSelected(const KFileItem&)));
  connect(m_mainWindow, SIGNAL(viewChanged()), this, SLOT(autoSyncFolder()));
}

KateFileBrowser::~KateFileBrowser()
{
}
//END Constroctor/Destrctor

//BEGIN Public Methods
void KateFileBrowser::setupToolbar()
{
  // remove all actions from the toolbar (there should be none)
  m_toolbar->clear();

  // create action list
  QList<QAction*> actions;
  actions << m_dirOperator->actionCollection()->action("back");
  actions << m_dirOperator->actionCollection()->action("forward");

  // bookmarks action!
  KActionMenu *acmBookmarks = new KActionMenu(KIcon("bookmarks"), i18n("Bookmarks"), this);
  acmBookmarks->setDelayed(false);
  m_bookmarkHandler = new KateBookmarkHandler(this, acmBookmarks->menu());
  acmBookmarks->setShortcutContext(Qt::WidgetWithChildrenShortcut);
  actions << acmBookmarks;

  // action for synchronising the dir operator with the current document path
  KAction* syncFolder = new KAction(this);
  syncFolder->setShortcutContext(Qt::WidgetWithChildrenShortcut);
  syncFolder->setText(i18n("Current Document Folder"));
  syncFolder->setIcon(KIcon("system-switch-user"));
  connect(syncFolder, SIGNAL(triggered()), this, SLOT(setActiveDocumentDir()));

  actions << syncFolder;

  // now add all actions to the toolbar
  foreach (QAction* ac, actions) {
    if (ac) {
      m_toolbar->addAction(ac);
    }
  }

  m_actionCollection->addAction("sync_dir", syncFolder);
  m_actionCollection->addAction("bookmarks", acmBookmarks);

  // section for settings menu
  KActionMenu *optionsMenu = new KActionMenu(KIcon("configure"), i18n("Options"), this);
  optionsMenu->setDelayed(false);
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("short view"));
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("detailed view"));
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("tree view"));
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("detailed tree view"));
  optionsMenu->addSeparator();
  optionsMenu->addAction(m_dirOperator->actionCollection()->action("show hidden"));

  // action for synchronising the dir operator with the current document path
  m_autoSyncFolder = new KAction(this);
  m_autoSyncFolder->setCheckable(true);
  m_autoSyncFolder->setText(i18n("Automatically synchronize with current document"));
  m_autoSyncFolder->setIcon(KIcon("system-switch-user"));
  connect(m_autoSyncFolder, SIGNAL(triggered()), this, SLOT(autoSyncFolder()));
  optionsMenu->addAction(m_autoSyncFolder);

  m_toolbar->addSeparator();
  m_toolbar->addAction(optionsMenu);
}

void KateFileBrowser::readSessionConfig(KConfigBase *config, const QString & name)
{
  KConfigGroup cgDir(config, name + ":dir");
  m_dirOperator->readConfig(cgDir);
  m_dirOperator->setView(KFile::Default);

  KConfigGroup cg(config, name);
  m_urlNavigator->setUrl(cg.readPathEntry("location", QDir::homePath()));
  setDir(cg.readPathEntry("location", QDir::homePath()));
  m_autoSyncFolder->setChecked(cg.readEntry("auto sync folder", false));
  m_filter->setHistoryItems(cg.readEntry("filter history", QStringList()), true);
}

void KateFileBrowser::writeSessionConfig(KConfigBase *config, const QString & name)
{
  KConfigGroup cgDir(config, name + ":dir");
  m_dirOperator->writeConfig(cgDir);

  KConfigGroup cg = KConfigGroup(config, name);
  cg.writePathEntry("location", m_urlNavigator->url().url());
  cg.writeEntry("auto sync folder", m_autoSyncFolder->isChecked());
  cg.writeEntry("filter history", m_filter->historyItems());
}

//END Public Methods

//BEGIN Public Slots

void KateFileBrowser::slotFilterChange(const QString & nf)
{
  QString f = '*' + nf.trimmed() + '*';
  const bool empty = f.isEmpty() || f == "*" || f == "**" || f == "***";

  if (empty) {
    m_dirOperator->clearFilter();
    m_filter->lineEdit()->clear();
  } else {
    m_dirOperator->setNameFilter(f);
  }

  m_dirOperator->updateDir();
}

bool kateFileSelectorIsReadable (const KUrl& url)
{
  if (!url.isLocalFile())
    return true; // what else can we say?

  QDir dir(url.toLocalFile());
  return dir.exists ();
}

void KateFileBrowser::setDir(KUrl u)
{
  KUrl newurl;

  if (!u.isValid())
    newurl.setPath(QDir::homePath());
  else
    newurl = u;

  QString pathstr = newurl.path(KUrl::AddTrailingSlash);
  newurl.setPath(pathstr);

  if (!kateFileSelectorIsReadable (newurl))
    newurl.cd(QString::fromLatin1(".."));

  if (!kateFileSelectorIsReadable (newurl))
    newurl.setPath(QDir::homePath());

  m_dirOperator->setUrl(newurl, true);
}

//END Public Slots

//BEGIN Private Slots

void KateFileBrowser::fileSelected(const KFileItem & /*file*/)
{
  openSelectedFiles();
}

void KateFileBrowser::openSelectedFiles()
{
  const KFileItemList list = m_dirOperator->selectedItems();

  foreach (const KFileItem& item, list)
  {
    m_mainWindow->openUrl(item.url());
  }

  m_dirOperator->view()->selectionModel()->clear();
}

void KateFileBrowser::updateDirOperator(const KUrl& u)
{
  m_dirOperator->setFocus();
  m_dirOperator->setUrl(u, true);
}

void KateFileBrowser::updateUrlNavigator(const KUrl& u)
{
  m_urlNavigator->setUrl(u);
}

void KateFileBrowser::setActiveDocumentDir()
{
//   kDebug(13001)<<"KateFileBrowser::setActiveDocumentDir()";
  KUrl u = activeDocumentUrl();
//   kDebug(13001)<<"URL: "<<u.prettyUrl();
  if (!u.isEmpty())
    setDir(u.upUrl());
//   kDebug(13001)<<"... setActiveDocumentDir() DONE!";
}

void KateFileBrowser::autoSyncFolder()
{
  if (m_autoSyncFolder->isChecked()) {
    setActiveDocumentDir();
  }
}

void KateFileBrowser::selectorViewChanged(QAbstractItemView * newView)
{
  newView->setSelectionMode(QAbstractItemView::ExtendedSelection);
}

//END Private Slots

//BEGIN Protected

KUrl KateFileBrowser::activeDocumentUrl()
{
  KTextEditor::View *v = m_mainWindow->activeView();
  if (v)
    return v->document()->url();
  return KUrl();
}
//END Protected

// kate: space-indent on; indent-width 2; replace-tabs on;
<|endoftext|>


<commit_before>#include "DataLikelihood.h"
#include "multichoose.h"
#include "multipermute.h"

long double
probObservedAllelesGivenGenotype(
        Sample& sample,
        Genotype& genotype,
        long double dependenceFactor,
        bool useMapQ) {

    int observationCount = sample.observationCount();
    vector<long double> alleleProbs = genotype.alleleProbabilities();
    vector<int> observationCounts = genotype.alleleObservationCounts(sample);
    int countOut = 0;
    long double prodQout = 0;  // the probability that the reads not in the genotype are all wrong

    for (Sample::iterator s = sample.begin(); s != sample.end(); ++s) {
        const string& base = s->first;
        if (!genotype.containsAllele(base)) {
            vector<Allele*>& alleles = s->second;
            if (useMapQ) {
                for (vector<Allele*>::iterator a = alleles.begin(); a != alleles.end(); ++a) {
                    prodQout += (*a)->lnquality + (*a)->lnmapQuality;
                }
            } else {
                for (vector<Allele*>::iterator a = alleles.begin(); a != alleles.end(); ++a) {
                    prodQout += (*a)->lnquality;
                }
            }
            countOut += alleles.size();
        }
    }

    // read dependence factor, asymptotically downgrade quality values of
    // successive reads to dependenceFactor * quality
    if (countOut > 1) {
        prodQout *= (1 + (countOut - 1) * dependenceFactor) / countOut;
    }

    if (sum(observationCounts) == 0) {
        return prodQout;
    } else {
        return prodQout + multinomialSamplingProbLn(alleleProbs, observationCounts);
    }

}

vector<pair<Genotype*, long double> >
probObservedAllelesGivenGenotypes(
        Sample& sample,
        vector<Genotype*>& genotypes,
        long double dependenceFactor,
        bool useMapQ) {
    vector<pair<Genotype*, long double> > results;
    for (vector<Genotype*>::iterator g = genotypes.begin(); g != genotypes.end(); ++g) {
        results.push_back(make_pair(*g, probObservedAllelesGivenGenotype(sample, **g, dependenceFactor, useMapQ)));
    }
    return results;
}
<commit_msg>take the minimum of base quality and mapping quality<commit_after>#include "DataLikelihood.h"
#include "multichoose.h"
#include "multipermute.h"

long double
probObservedAllelesGivenGenotype(
        Sample& sample,
        Genotype& genotype,
        long double dependenceFactor,
        bool useMapQ) {

    int observationCount = sample.observationCount();
    vector<long double> alleleProbs = genotype.alleleProbabilities();
    vector<int> observationCounts = genotype.alleleObservationCounts(sample);
    int countOut = 0;
    long double prodQout = 0;  // the probability that the reads not in the genotype are all wrong

    for (Sample::iterator s = sample.begin(); s != sample.end(); ++s) {
        const string& base = s->first;
        if (!genotype.containsAllele(base)) {
            vector<Allele*>& alleles = s->second;
            if (useMapQ) {
                for (vector<Allele*>::iterator a = alleles.begin(); a != alleles.end(); ++a) {
                    // take the lesser of mapping quality and base quality (in log space)
                    prodQout += max((*a)->lnquality, (*a)->lnmapQuality);
                }
            } else {
                for (vector<Allele*>::iterator a = alleles.begin(); a != alleles.end(); ++a) {
                    prodQout += (*a)->lnquality;
                }
            }
            countOut += alleles.size();
        }
    }

    // read dependence factor, asymptotically downgrade quality values of
    // successive reads to dependenceFactor * quality
    if (countOut > 1) {
        prodQout *= (1 + (countOut - 1) * dependenceFactor) / countOut;
    }

    if (sum(observationCounts) == 0) {
        return prodQout;
    } else {
        return prodQout + multinomialSamplingProbLn(alleleProbs, observationCounts);
    }

}

vector<pair<Genotype*, long double> >
probObservedAllelesGivenGenotypes(
        Sample& sample,
        vector<Genotype*>& genotypes,
        long double dependenceFactor,
        bool useMapQ) {
    vector<pair<Genotype*, long double> > results;
    for (vector<Genotype*>::iterator g = genotypes.begin(); g != genotypes.end(); ++g) {
        results.push_back(make_pair(*g, probObservedAllelesGivenGenotype(sample, **g, dependenceFactor, useMapQ)));
    }
    return results;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Dan Leinir Turthra Jensen <admin@leinir.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "prefabprivate.h"

#include "engine/gameobject.h"
#include "prefabinstance.h"
#include "prefabinstancechild.h"

using namespace GluonEngine;

PrefabPrivate::PrefabPrivate()
    : gameObject( 0 )
    , preCacheSize( 0 )
    , additionalCacheSize( 0 )
{
}

PrefabPrivate::PrefabPrivate( const PrefabPrivate& other )
    : instances( other.instances )
    , gameObject( other.gameObject )
    , preCacheSize( 0 )
    , additionalCacheSize( 0 )
{
}

PrefabPrivate::~PrefabPrivate()
{
    delete( gameObject );
}

void PrefabPrivate::updateChildrenFromOther(GluonCore::GluonObject* updateThis, const GluonCore::GluonObject* updateFrom)
{
    // Firstly, we have to ensure the children are in the right place (otherwise the next bit might
    // not function correctly)
    moveChildrenIntoPlace(updateThis, updateFrom);
    removeAndAddChildren(updateThis, updateFrom);

}

void PrefabPrivate::moveChildrenIntoPlace(GluonCore::GluonObject* updateThis, const GluonCore::GluonObject* updateFrom)
{
    // Go through all children recursively on "updateFrom" and...
    foreach(QObject* child, updateFrom->children())
    {
        GluonCore::GluonObject* childObject = qobject_cast<GluonCore::GluonObject*>(child);
        if(!childObject)
            continue;

        // operate on a local list of children, so as to easily allow for the removal of children
        // in the end
        QObjectList otherChildList = updateThis->children();

        foreach(QObject* otherChild, otherChildList)
        {
            GluonCore::GluonObject* otherChildObject = qobject_cast<GluonCore::GluonObject*>(otherChild);
            if(!otherChildObject)
                continue;

            // recurse...
            moveChildrenIntoPlace(otherChildObject, childObject);
            otherChildList.removeOne(otherChild);
        }

        // If there are children left in the list...
        foreach(QObject* otherChild, otherChildList)
        {
            otherChild->deleteLater();
        }
    }
}

void PrefabPrivate::removeAndAddChildren(GluonCore::GluonObject* updateThis, const GluonCore::GluonObject* updateFrom)
{
    // Go through all children on "updateThis" and remove all objects which no longer
    // exist on updateFrom
    foreach(QObject* child, updateThis->children())
    {
        GluonCore::GluonObject* childObject = qobject_cast<GluonCore::GluonObject*>(child);
        if(!childObject)
            continue;

        // Check if the child in the item we're updating still exists in the item we're updating from
        QString qualifiedName = childObject->qualifiedName(gameObject);
        GluonCore::GluonObject* otherChild = updateFrom->findItemByName(qualifiedName);
        if(!otherChild)
        {
            // If we've not found the child, that means it was deleted, and we should remove it
            // from here as well
            updateThis->removeChild(childObject);
            childObject->deleteLater();

            // Remove object with same name on all linked instances
            foreach(PrefabInstance* linkedInstance, instances)
            {
                GluonCore::GluonObject* linkedChild = linkedInstance->findItemByName(qualifiedName);
                if(linkedChild)
                {
                    GluonCore::GluonObject* linkedParent = qobject_cast< GluonCore::GluonObject* >(linkedChild->parent());
                    linkedParent->removeChild(linkedChild);
                    linkedChild->deleteLater();
                }
            }
        }
    }

    // Go through all children on "updateFrom" and add all new objects to updateThis
    foreach(QObject* child, updateFrom->children())
    {
        GluonCore::GluonObject* childObject = qobject_cast<GluonCore::GluonObject*>(child);
        if(!childObject)
            continue;

        // Check if the child in the item we're updating from exists in the item we're updating
        GluonCore::GluonObject* otherChild = updateThis->findItemByName(childObject->name());
        if(!otherChild)
        {
            // Clone the new child...
            QString qualifiedName = otherChild->qualifiedName(gameObject);
            GluonCore::GluonObject* clone = otherChild->clone(updateThis);

            // - add object in same position on all linked instances
            foreach(PrefabInstance* linkedInstance, instances)
            {
                if(qobject_cast<GameObject*>(clone))
                {
                    // If new object is a GameObject, we need to add it as a PrefabInstanceChild...
                    PrefabInstanceChild* newChildInstance = new PrefabInstanceChild();
                    linkedInstance->addChild(newChildInstance);
                    // Clone the tree from the cloned GameObject
                    newChildInstance->cloneFromGameObject(qobject_cast<GameObject*>(clone));
                }
                else
                {
                    // Otherwise, just clone it verbatim
                    GluonCore::GluonObject* newInstanceChild = clone->clone(linkedInstance);
                    // Reclone properties
                    Prefab::cloneObjectProperties(newInstanceChild, clone);
                }
            }
        }
    }

    // Finally. go through all children on "updateFrom" and...
    foreach(QObject* child, updateFrom->children())
    {
        GluonCore::GluonObject* childObject = qobject_cast<GluonCore::GluonObject*>(child);
        if(!childObject)
            continue;
        //...recurse
        GluonCore::GluonObject* otherChildObject = updateThis->findItemByName(childObject->name());
        if(otherChildObject)
            removeAndAddChildren(otherChildObject, childObject);
    }
}
<commit_msg>clone() already clones properties, no need to do it again<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Dan Leinir Turthra Jensen <admin@leinir.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "prefabprivate.h"

#include "engine/gameobject.h"
#include "prefabinstance.h"
#include "prefabinstancechild.h"

using namespace GluonEngine;

PrefabPrivate::PrefabPrivate()
    : gameObject( 0 )
    , preCacheSize( 0 )
    , additionalCacheSize( 0 )
{
}

PrefabPrivate::PrefabPrivate( const PrefabPrivate& other )
    : instances( other.instances )
    , gameObject( other.gameObject )
    , preCacheSize( 0 )
    , additionalCacheSize( 0 )
{
}

PrefabPrivate::~PrefabPrivate()
{
    delete( gameObject );
}

void PrefabPrivate::updateChildrenFromOther(GluonCore::GluonObject* updateThis, const GluonCore::GluonObject* updateFrom)
{
    // Firstly, we have to ensure the children are in the right place (otherwise the next bit might
    // not function correctly)
    moveChildrenIntoPlace(updateThis, updateFrom);
    removeAndAddChildren(updateThis, updateFrom);

}

void PrefabPrivate::moveChildrenIntoPlace(GluonCore::GluonObject* updateThis, const GluonCore::GluonObject* updateFrom)
{
    // Go through all children recursively on "updateFrom" and...
    foreach(QObject* child, updateFrom->children())
    {
        GluonCore::GluonObject* childObject = qobject_cast<GluonCore::GluonObject*>(child);
        if(!childObject)
            continue;

        // operate on a local list of children, so as to easily allow for the removal of children
        // in the end
        QObjectList otherChildList = updateThis->children();

        foreach(QObject* otherChild, otherChildList)
        {
            GluonCore::GluonObject* otherChildObject = qobject_cast<GluonCore::GluonObject*>(otherChild);
            if(!otherChildObject)
                continue;

            // recurse...
            moveChildrenIntoPlace(otherChildObject, childObject);
            otherChildList.removeOne(otherChild);
        }

        // If there are children left in the list...
        foreach(QObject* otherChild, otherChildList)
        {
            otherChild->deleteLater();
        }
    }
}

void PrefabPrivate::removeAndAddChildren(GluonCore::GluonObject* updateThis, const GluonCore::GluonObject* updateFrom)
{
    // Go through all children on "updateThis" and remove all objects which no longer
    // exist on updateFrom
    foreach(QObject* child, updateThis->children())
    {
        GluonCore::GluonObject* childObject = qobject_cast<GluonCore::GluonObject*>(child);
        if(!childObject)
            continue;

        // Check if the child in the item we're updating still exists in the item we're updating from
        QString qualifiedName = childObject->qualifiedName(gameObject);
        GluonCore::GluonObject* otherChild = updateFrom->findItemByName(qualifiedName);
        if(!otherChild)
        {
            // If we've not found the child, that means it was deleted, and we should remove it
            // from here as well
            updateThis->removeChild(childObject);
            childObject->deleteLater();

            // Remove object with same name on all linked instances
            foreach(PrefabInstance* linkedInstance, instances)
            {
                GluonCore::GluonObject* linkedChild = linkedInstance->findItemByName(qualifiedName);
                if(linkedChild)
                {
                    GluonCore::GluonObject* linkedParent = qobject_cast< GluonCore::GluonObject* >(linkedChild->parent());
                    linkedParent->removeChild(linkedChild);
                    linkedChild->deleteLater();
                }
            }
        }
    }

    // Go through all children on "updateFrom" and add all new objects to updateThis
    foreach(QObject* child, updateFrom->children())
    {
        GluonCore::GluonObject* childObject = qobject_cast<GluonCore::GluonObject*>(child);
        if(!childObject)
            continue;

        // Check if the child in the item we're updating from exists in the item we're updating
        GluonCore::GluonObject* otherChild = updateThis->findItemByName(childObject->name());
        if(!otherChild)
        {
            // Clone the new child...
            QString qualifiedName = otherChild->qualifiedName(gameObject);
            GluonCore::GluonObject* clone = otherChild->clone(updateThis);

            // - add object in same position on all linked instances
            foreach(PrefabInstance* linkedInstance, instances)
            {
                if(qobject_cast<GameObject*>(clone))
                {
                    // If new object is a GameObject, we need to add it as a PrefabInstanceChild...
                    PrefabInstanceChild* newChildInstance = new PrefabInstanceChild();
                    linkedInstance->addChild(newChildInstance);
                    // Clone the tree from the cloned GameObject
                    newChildInstance->cloneFromGameObject(qobject_cast<GameObject*>(clone));
                }
                else
                {
                    // Otherwise, just clone it verbatim
                    GluonCore::GluonObject* newInstanceChild = clone->clone(linkedInstance);
                }
            }
        }
    }

    // Finally. go through all children on "updateFrom" and...
    foreach(QObject* child, updateFrom->children())
    {
        GluonCore::GluonObject* childObject = qobject_cast<GluonCore::GluonObject*>(child);
        if(!childObject)
            continue;
        //...recurse
        GluonCore::GluonObject* otherChildObject = updateThis->findItemByName(childObject->name());
        if(otherChildObject)
            removeAndAddChildren(otherChildObject, childObject);
    }
}
<|endoftext|>


<commit_before>/**
 * @file
 * @author Jason Lingle
 * @date 2012.02.04
 * @brief Implementation of NetworkConnection class
 */

#include <iostream>

#include <SDL.h>

#include "network_connection.hxx"
#include "network_assembly.hxx"
#include "network_geraet.hxx"
#include "antenna.hxx"
#include "io.hxx"

#include "src/sim/game_field.hxx"
#include "src/sim/game_object.hxx"

using namespace std;

NetworkConnection::geraetNumMap_t* NetworkConnection::geraetNumMap;

NetworkConnection::NetworkConnection(NetworkAssembly* assembly_,
                                     const Antenna::endpoint& endpoint_,
                                     bool incomming)
: field(assembly_->field->width, assembly_->field->height),
  nextOutSeq(0),
  greatestSeq(0),
  latency(0),
  lastIncommingTime(SDL_GetTicks()),
  status(incomming? Established : Connecting),
  endpoint(endpoint_),
  parent(assembly_),
  scg(NULL) //TODO: replace with actual object later
{
  //TODO: put SCG in channel map
}

NetworkConnection::~NetworkConnection() {
  //scg is stored within the channel map, so we don't have to explicitly
  //delete it.
  for (geraete_t::const_iterator it = geraete.begin();
       it != geraete.end(); ++it)
    delete it->second;
}

void NetworkConnection::update(unsigned et) noth {
  //TODO: do something
}

void NetworkConnection::process(const Antenna::endpoint& source,
                                Antenna* antenna, Tuner* tuner,
                                const byte* data, unsigned datlen)
noth {
  if (datlen < 4) {
    //Packet does not even have a header
    #ifdef DEBUG
    cerr << "Warning: Dropping packet of length " << datlen
         << " from source " << source << endl;
    #endif
    return;
  }

  channel chan;
  seq_t seq;
  io::read(data, seq);
  io::read(data, chan);
  datlen -= 4;

  //Range check
  if (seq-greatestSeq < 1024 || greatestSeq-seq < 1024) {
    //Dupe check
    if (recentlyReceived.count(seq) == 0) {
      //Possibly update greatestSeq
      if (seq-greatestSeq < 1024)
        greatestSeq = seq;

      //OK, add to set and queue, possibly trim both
      recentlyReceived.insert(seq);
      recentlyReceivedQueue.push_back(seq);
      if (recentlyReceivedQueue.size() > 1024) {
        recentlyReceived.erase(recentlyReceivedQueue.front());
        recentlyReceivedQueue.pop_front();
      }

      //Accept packet; does the channel exist?
      chanmap_t::const_iterator it = locchan.find(chan);
      if (it != locchan.end()) {
        it->second->receive(seq, data, datlen);
      } else {
        #ifdef DEBUG
        cerr << "Warning: Dropping packet to closed channel " << chan
             << " from source " << source << endl;
        #endif
      }
    }
  } else {
    #ifdef DEBUG
    cerr << "Warning: Dropping packet of seq " << seq
         << " due to range check; greatestSeq = " << greatestSeq
         << "; from source " << source << endl;
    #endif
  }
}
<commit_msg>Maintain lastIncommingTime in NetworkConnection.<commit_after>/**
 * @file
 * @author Jason Lingle
 * @date 2012.02.04
 * @brief Implementation of NetworkConnection class
 */

#include <iostream>

#include <SDL.h>

#include "network_connection.hxx"
#include "network_assembly.hxx"
#include "network_geraet.hxx"
#include "antenna.hxx"
#include "io.hxx"

#include "src/sim/game_field.hxx"
#include "src/sim/game_object.hxx"

using namespace std;

NetworkConnection::geraetNumMap_t* NetworkConnection::geraetNumMap;

NetworkConnection::NetworkConnection(NetworkAssembly* assembly_,
                                     const Antenna::endpoint& endpoint_,
                                     bool incomming)
: field(assembly_->field->width, assembly_->field->height),
  nextOutSeq(0),
  greatestSeq(0),
  latency(0),
  lastIncommingTime(SDL_GetTicks()),
  status(incomming? Established : Connecting),
  endpoint(endpoint_),
  parent(assembly_),
  scg(NULL) //TODO: replace with actual object later
{
  //TODO: put SCG in channel map
}

NetworkConnection::~NetworkConnection() {
  //scg is stored within the channel map, so we don't have to explicitly
  //delete it.
  for (geraete_t::const_iterator it = geraete.begin();
       it != geraete.end(); ++it)
    delete it->second;
}

void NetworkConnection::update(unsigned et) noth {
  //TODO: do something
}

void NetworkConnection::process(const Antenna::endpoint& source,
                                Antenna* antenna, Tuner* tuner,
                                const byte* data, unsigned datlen)
noth {
  if (datlen < 4) {
    //Packet does not even have a header
    #ifdef DEBUG
    cerr << "Warning: Dropping packet of length " << datlen
         << " from source " << source << endl;
    #endif
    return;
  }

  channel chan;
  seq_t seq;
  io::read(data, seq);
  io::read(data, chan);
  datlen -= 4;

  //Range check
  if (seq-greatestSeq < 1024 || greatestSeq-seq < 1024) {
    //Dupe check
    if (recentlyReceived.count(seq) == 0) {
      //Possibly update greatestSeq
      if (seq-greatestSeq < 1024)
        greatestSeq = seq;

      //OK, add to set and queue, possibly trim both
      recentlyReceived.insert(seq);
      recentlyReceivedQueue.push_back(seq);
      if (recentlyReceivedQueue.size() > 1024) {
        recentlyReceived.erase(recentlyReceivedQueue.front());
        recentlyReceivedQueue.pop_front();
      }

      //Update time of most recent receive
      lastIncommingTime = SDL_GetTicks();

      //Accept packet; does the channel exist?
      chanmap_t::const_iterator it = locchan.find(chan);
      if (it != locchan.end()) {
        it->second->receive(seq, data, datlen);
      } else {
        #ifdef DEBUG
        cerr << "Warning: Dropping packet to closed channel " << chan
             << " from source " << source << endl;
        #endif
      }
    }
  } else {
    #ifdef DEBUG
    cerr << "Warning: Dropping packet of seq " << seq
         << " due to range check; greatestSeq = " << greatestSeq
         << "; from source " << source << endl;
    #endif
  }
}
<|endoftext|>


<commit_before>#include <Arduino.h>

#include "DollhousePanel.h"
#include "TimingHelpers.h"

#include <Adafruit_TLC59711.h>
#include <Adafruit_NeoPixel.h>
#include <LiquidCrystal.h>
#include <SPI.h>
#include <Fsm.h>
#include <EnableInterrupt.h>

const char NUM_TLC59711 = 1;
const char TLC_DATA = 12;
const char TLC_CLK = 13;

const char PIXEL_COUNT = 3;
const char PIXEL_PIN = 8;

enum events {
  CHANGE_LIGHT_MODE,
  NEXT_ROOM,
  PREVIOUS_ROOM,
  RESET_ROOMS
};

// Lighting modes finite state machine
State state_lighting_mode(on_lighting_mode_enter, NULL, &on_lighting_mode_exit);
State state_party_mode(on_party_mode_enter, NULL, &on_party_mode_exit);
State state_nitelite_mode(on_nitelite_mode_enter, NULL, &on_nitelite_mode_exit);
State state_off_mode(on_off_mode_enter, NULL, &on_off_mode_exit);
Fsm modes(&state_off_mode);

enum Modes {
  LIGHTING_MODE,
  PARTY_MODE,
  NITELITE_MODE,
  OFF_MODE
};

String modeNames[] = {"Lighting", "Party", "Nitelite", "Off"};

// Rooms finite state machine
State state_all_rooms(on_all_enter, NULL, &on_all_exit);
State state_hall(on_hall_enter, NULL, &on_hall_exit);
State state_living_room(on_living_room_enter, NULL, &on_living_room_exit);
State state_kitchen(on_kitchen_enter, NULL, &on_kitchen_exit);
State state_bedroom(on_bedroom_enter, NULL, &on_bedroom_exit);
State state_bathroom(on_bathroom_enter, NULL, &on_bathroom_exit);
State state_attic(on_attic_enter, NULL, &on_attic_exit);
Fsm rooms(&state_all_rooms);

// LastROOM is included to make it easier to figure out the size of the enum
// for things like sizing the brightness state array
enum Rooms {
  ALL_ROOMS,
  LIVING_ROOM,
  HALL,
  KITCHEN,
  BEDROOM,
  BATHROOM,
  ATTIC,
  LastROOM
};

String roomNames[] = {"All", "Living", "Hall", "Kitchen", "Bedroom", "Bathroom", "Attic"};

// NeoPixels (for the attic & !!!PARTY MODE!!!)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

// PWM board (controls the room lights)
Adafruit_TLC59711 tlc = Adafruit_TLC59711(NUM_TLC59711, TLC_CLK, TLC_DATA);

// 16x2 LCD display
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

// Panel RGB LED pins
const char RED_PIN = 9;
const char GREEN_PIN = 10;
const char BLUE_PIN = 11;

int brightness = 90;
int deltaLevel = 30;
int minLevel = 0;
int maxLevel = 180;
int roomBrightness[LastROOM];
int currentRoom = ALL_ROOMS;
int currentMode = OFF_MODE;

int debounceDelay = 150;
long timeDebounce = 0;

void setup() {
  // Fire up the LCD display
  lcd.begin(16, 2);

  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);

  // initialize the NeoPixel strand
  strip.begin();
  strip.show();

  // Initialize the PWM board
  tlc.begin();
  tlc.write();

  // set defualt room brightness
  setDefaultLightLevel();

  // enable interrupts on buttons
  // The button interface is a Smartmaker 5A5 (annoying, but it works)
  enableInterrupt(A0, handleButtonOne, FALLING);
  enableInterrupt(A1, handleButtonTwo, FALLING);
  enableInterrupt(A2, handleButtonThree, FALLING);
  enableInterrupt(A3, handleButtonFour, FALLING);
  enableInterrupt(A4, handleButtonFive, FALLING);

  // mode FSM transitions
  modes.add_transition(&state_off_mode, &state_lighting_mode, CHANGE_LIGHT_MODE, NULL);
  modes.add_transition(&state_lighting_mode, &state_party_mode, CHANGE_LIGHT_MODE, NULL);
  modes.add_transition(&state_party_mode, &state_nitelite_mode, CHANGE_LIGHT_MODE, NULL);
  modes.add_transition(&state_nitelite_mode, &state_off_mode, CHANGE_LIGHT_MODE, NULL);

  // rooms FSM transitions
  // looping "forward" through the rooms
  rooms.add_transition(&state_all_rooms, &state_hall, NEXT_ROOM, NULL);
  rooms.add_transition(&state_hall, &state_living_room, NEXT_ROOM, NULL);
  rooms.add_transition(&state_living_room, &state_kitchen, NEXT_ROOM, NULL);
  rooms.add_transition(&state_kitchen, &state_bedroom, NEXT_ROOM, NULL);
  rooms.add_transition(&state_bedroom, &state_bathroom, NEXT_ROOM, NULL);
  rooms.add_transition(&state_bathroom, &state_attic, NEXT_ROOM, NULL);
  rooms.add_transition(&state_attic, &state_all_rooms, NEXT_ROOM, NULL);

  // looping "backward" through the rooms
  rooms.add_transition(&state_all_rooms, &state_attic, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_attic, &state_bathroom, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_bathroom, &state_bedroom, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_bedroom, &state_kitchen, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_kitchen, &state_living_room, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_living_room, &state_hall, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_hall, &state_all_rooms, PREVIOUS_ROOM, NULL);

  // resetting to the default room (all rooms)
  rooms.add_transition(&state_hall, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_living_room, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_kitchen, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_bedroom, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_bathroom, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_attic, &state_all_rooms, RESET_ROOMS, NULL);

  // run each state machine once to initialize them; this is basically a NOOP
  // thanks the default state
  rooms.run_machine();
  modes.run_machine();

  lcd.clear();
  lcd.print("Doll house");
  lcd.setCursor(0,1);
  lcd.print("lighting!");
}

// ***** Button event handlers ***** //

// Use button one to set the light mode for all rooms
void handleButtonOne() {
  if (!still_bouncing()) {
    lcd.clear();
    rooms.trigger(RESET_ROOMS);
    modes.trigger(CHANGE_LIGHT_MODE);
  }
}

// Use button two to increase brightness for the current room
void handleButtonTwo() {
  if (!still_bouncing()) {
    setRoomBrightness(currentRoom, min(roomBrightness[currentRoom] + deltaLevel, maxLevel));
    printCurrentRoom();
  }
}

// Use button three to select the previous room
void handleButtonThree() {
  if (!still_bouncing()) {
    lcd.clear();
    rooms.trigger(PREVIOUS_ROOM);
  }
}

// Use button four to decrease brightness for the current room
void handleButtonFour() {
  if (!still_bouncing()) {
    setRoomBrightness(currentRoom, max(roomBrightness[currentRoom] - deltaLevel, minLevel));
    printCurrentRoom();
  }
}

// Use button five to select the next room
void handleButtonFive() {
  if (!still_bouncing()) {
    lcd.clear();
    rooms.trigger(NEXT_ROOM);
  }
}

// ***** helpers ***** //

void setRGBColor(int red, int green, int blue) {
  int myRed = constrain(red, 0, 255);
  int myGreen = constrain(green, 0, 255);
  int myBlue = constrain(blue, 0, 255);

  analogWrite(RED_PIN, myRed);
  analogWrite(GREEN_PIN, myGreen);
  analogWrite(BLUE_PIN, myBlue);
}

void setRoomBrightness(int room, int level) {
  setRGBColor(0,0,level);
  roomBrightness[room] = level;
  tlc.setPWM(room * 3, roomBrightness[room] * maxLevel);
  tlc.write();
}

void setDefaultLightLevel() {
  setRGBColor(0,0,brightness);
  for (int i = 0; i != LastROOM; i++) {
    roomBrightness[i] = brightness;
  }
}

void setCurrentMode(int mode) {
  currentMode = mode;
  printCurrentMode();
}

void printCurrentMode() {
  lcd.clear();
  lcd.print("Mode: ");
  lcd.print(modeNames[currentMode]);
}

void setCurrentRoom(int room) {
  currentRoom = room;
  setRGBColor(0,0,roomBrightness[room]);
  printCurrentRoom();
}

void printCurrentRoom() {
  lcd.clear();
  lcd.print("room: ");
  lcd.print(roomNames[currentRoom]);
  lcd.setCursor(0,1);
  lcd.print("brightness: ");
  lcd.print(roomBrightness[currentRoom]);
}

// ***** FSM event handlers ***** //

// ---- lighting mode states ---- //

void on_lighting_mode_enter(){
  setCurrentMode(LIGHTING_MODE);
}

void on_lighting_mode_exit(){

}

void on_party_mode_enter(){
  setCurrentMode(PARTY_MODE);
}

void on_party_mode_exit(){

}

void on_nitelite_mode_enter(){
  setCurrentMode(NITELITE_MODE);
}

void on_nitelite_mode_exit(){

}

void on_off_mode_enter(){
  setCurrentMode(OFF_MODE);
}

void on_off_mode_exit(){

}

// ---- room selection states ---- //
void on_all_enter() {
  setCurrentRoom(ALL_ROOMS);
}

void on_all_exit() {

}

void on_hall_enter() {
  setCurrentRoom(HALL);
}

void on_hall_exit() {

}

void on_living_room_enter() {
  setCurrentRoom(LIVING_ROOM);
}

void on_living_room_exit() {

}

void on_kitchen_enter() {
  setCurrentRoom(KITCHEN);
}

void on_kitchen_exit() {

}

void on_bathroom_enter() {
  setCurrentRoom(BATHROOM);
}

void on_bathroom_exit() {

}

void on_bedroom_enter() {
  setCurrentRoom(BEDROOM);
}

void on_bedroom_exit() {

}

void on_attic_enter() {
  setCurrentRoom(ATTIC);
}

void on_attic_exit() {

}

// Debonce timer
boolean still_bouncing() {
  // If the debounce timer is not running, then we can assume the buttons
  // aren't bouncing because nothing has been pressed recently
  if (timerDebounce == 0) {
    startTimer(timerDebounce);
    return false;
  }

  if (timerIsExpired(timerDebounce, debounceDelay)) {
    clearTimer(timerDebounce);
    startTimer(timerDebounce);
    return false;
  }

  return true;
}

void loop() {
  // do nothing; everything is handled via FSM events.
  // We also don't need to call the ".run_machine" methods of
  // the FSMs as there are no "on_state" handlers or timed transitions
}
<commit_msg>Fixed timer<commit_after>#include <Arduino.h>

#include "DollhousePanel.h"
#include "TimingHelpers.h"

#include <Adafruit_TLC59711.h>
#include <Adafruit_NeoPixel.h>
#include <LiquidCrystal.h>
#include <SPI.h>
#include <Fsm.h>
#include <EnableInterrupt.h>

const char NUM_TLC59711 = 1;
const char TLC_DATA = 12;
const char TLC_CLK = 13;

const char PIXEL_COUNT = 3;
const char PIXEL_PIN = 8;

enum events {
  CHANGE_LIGHT_MODE,
  NEXT_ROOM,
  PREVIOUS_ROOM,
  RESET_ROOMS
};

// Lighting modes finite state machine
State state_lighting_mode(on_lighting_mode_enter, NULL, &on_lighting_mode_exit);
State state_party_mode(on_party_mode_enter, NULL, &on_party_mode_exit);
State state_nitelite_mode(on_nitelite_mode_enter, NULL, &on_nitelite_mode_exit);
State state_off_mode(on_off_mode_enter, NULL, &on_off_mode_exit);
Fsm modes(&state_off_mode);

enum Modes {
  LIGHTING_MODE,
  PARTY_MODE,
  NITELITE_MODE,
  OFF_MODE
};

String modeNames[] = {"Lighting", "Party", "Nitelite", "Off"};

// Rooms finite state machine
State state_all_rooms(on_all_enter, NULL, &on_all_exit);
State state_hall(on_hall_enter, NULL, &on_hall_exit);
State state_living_room(on_living_room_enter, NULL, &on_living_room_exit);
State state_kitchen(on_kitchen_enter, NULL, &on_kitchen_exit);
State state_bedroom(on_bedroom_enter, NULL, &on_bedroom_exit);
State state_bathroom(on_bathroom_enter, NULL, &on_bathroom_exit);
State state_attic(on_attic_enter, NULL, &on_attic_exit);
Fsm rooms(&state_all_rooms);

// LastROOM is included to make it easier to figure out the size of the enum
// for things like sizing the brightness state array
enum Rooms {
  ALL_ROOMS,
  LIVING_ROOM,
  HALL,
  KITCHEN,
  BEDROOM,
  BATHROOM,
  ATTIC,
  LastROOM
};

String roomNames[] = {"All", "Living", "Hall", "Kitchen", "Bedroom", "Bathroom", "Attic"};

// NeoPixels (for the attic & !!!PARTY MODE!!!)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

// PWM board (controls the room lights)
Adafruit_TLC59711 tlc = Adafruit_TLC59711(NUM_TLC59711, TLC_CLK, TLC_DATA);

// 16x2 LCD display
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

// Panel RGB LED pins
const char RED_PIN = 9;
const char GREEN_PIN = 10;
const char BLUE_PIN = 11;

int brightness = 90;
int deltaLevel = 30;
int minLevel = 0;
int maxLevel = 180;
int roomBrightness[LastROOM];
int currentRoom = ALL_ROOMS;
int currentMode = OFF_MODE;

int debounceDelay = 150;
long timerDebounce = 0;

void setup() {
  // Fire up the LCD display
  lcd.begin(16, 2);

  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);

  // initialize the NeoPixel strand
  strip.begin();
  strip.show();

  // Initialize the PWM board
  tlc.begin();
  tlc.write();

  // set defualt room brightness
  setDefaultLightLevel();

  // enable interrupts on buttons
  // The button interface is a Smartmaker 5A5 (annoying, but it works)
  enableInterrupt(A0, handleButtonOne, FALLING);
  enableInterrupt(A1, handleButtonTwo, FALLING);
  enableInterrupt(A2, handleButtonThree, FALLING);
  enableInterrupt(A3, handleButtonFour, FALLING);
  enableInterrupt(A4, handleButtonFive, FALLING);

  // mode FSM transitions
  modes.add_transition(&state_off_mode, &state_lighting_mode, CHANGE_LIGHT_MODE, NULL);
  modes.add_transition(&state_lighting_mode, &state_party_mode, CHANGE_LIGHT_MODE, NULL);
  modes.add_transition(&state_party_mode, &state_nitelite_mode, CHANGE_LIGHT_MODE, NULL);
  modes.add_transition(&state_nitelite_mode, &state_off_mode, CHANGE_LIGHT_MODE, NULL);

  // rooms FSM transitions
  // looping "forward" through the rooms
  rooms.add_transition(&state_all_rooms, &state_hall, NEXT_ROOM, NULL);
  rooms.add_transition(&state_hall, &state_living_room, NEXT_ROOM, NULL);
  rooms.add_transition(&state_living_room, &state_kitchen, NEXT_ROOM, NULL);
  rooms.add_transition(&state_kitchen, &state_bedroom, NEXT_ROOM, NULL);
  rooms.add_transition(&state_bedroom, &state_bathroom, NEXT_ROOM, NULL);
  rooms.add_transition(&state_bathroom, &state_attic, NEXT_ROOM, NULL);
  rooms.add_transition(&state_attic, &state_all_rooms, NEXT_ROOM, NULL);

  // looping "backward" through the rooms
  rooms.add_transition(&state_all_rooms, &state_attic, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_attic, &state_bathroom, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_bathroom, &state_bedroom, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_bedroom, &state_kitchen, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_kitchen, &state_living_room, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_living_room, &state_hall, PREVIOUS_ROOM, NULL);
  rooms.add_transition(&state_hall, &state_all_rooms, PREVIOUS_ROOM, NULL);

  // resetting to the default room (all rooms)
  rooms.add_transition(&state_hall, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_living_room, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_kitchen, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_bedroom, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_bathroom, &state_all_rooms, RESET_ROOMS, NULL);
  rooms.add_transition(&state_attic, &state_all_rooms, RESET_ROOMS, NULL);

  // run each state machine once to initialize them; this is basically a NOOP
  // thanks the default state
  rooms.run_machine();
  modes.run_machine();

  lcd.clear();
  lcd.print("Doll house");
  lcd.setCursor(0,1);
  lcd.print("lighting!");
}

// ***** Button event handlers ***** //

// Use button one to set the light mode for all rooms
void handleButtonOne() {
  if (!still_bouncing()) {
    lcd.clear();
    rooms.trigger(RESET_ROOMS);
    modes.trigger(CHANGE_LIGHT_MODE);
  }
}

// Use button two to increase brightness for the current room
void handleButtonTwo() {
  if (!still_bouncing()) {
    setRoomBrightness(currentRoom, min(roomBrightness[currentRoom] + deltaLevel, maxLevel));
    printCurrentRoom();
  }
}

// Use button three to select the previous room
void handleButtonThree() {
  if (!still_bouncing()) {
    lcd.clear();
    rooms.trigger(PREVIOUS_ROOM);
  }
}

// Use button four to decrease brightness for the current room
void handleButtonFour() {
  if (!still_bouncing()) {
    setRoomBrightness(currentRoom, max(roomBrightness[currentRoom] - deltaLevel, minLevel));
    printCurrentRoom();
  }
}

// Use button five to select the next room
void handleButtonFive() {
  if (!still_bouncing()) {
    lcd.clear();
    rooms.trigger(NEXT_ROOM);
  }
}

// ***** helpers ***** //

void setRGBColor(int red, int green, int blue) {
  int myRed = constrain(red, 0, 255);
  int myGreen = constrain(green, 0, 255);
  int myBlue = constrain(blue, 0, 255);

  analogWrite(RED_PIN, myRed);
  analogWrite(GREEN_PIN, myGreen);
  analogWrite(BLUE_PIN, myBlue);
}

void setRoomBrightness(int room, int level) {
  setRGBColor(0,0,level);
  roomBrightness[room] = level;
  tlc.setPWM(room * 3, roomBrightness[room] * maxLevel);
  tlc.write();
}

void setDefaultLightLevel() {
  setRGBColor(0,0,brightness);
  for (int i = 0; i != LastROOM; i++) {
    roomBrightness[i] = brightness;
  }
}

void setCurrentMode(int mode) {
  currentMode = mode;
  printCurrentMode();
}

void printCurrentMode() {
  lcd.clear();
  lcd.print("Mode: ");
  lcd.print(modeNames[currentMode]);
}

void setCurrentRoom(int room) {
  currentRoom = room;
  setRGBColor(0,0,roomBrightness[room]);
  printCurrentRoom();
}

void printCurrentRoom() {
  lcd.clear();
  lcd.print("room: ");
  lcd.print(roomNames[currentRoom]);
  lcd.setCursor(0,1);
  lcd.print("brightness: ");
  lcd.print(roomBrightness[currentRoom]);
}

// ***** FSM event handlers ***** //

// ---- lighting mode states ---- //

void on_lighting_mode_enter(){
  setCurrentMode(LIGHTING_MODE);
}

void on_lighting_mode_exit(){

}

void on_party_mode_enter(){
  setCurrentMode(PARTY_MODE);
}

void on_party_mode_exit(){

}

void on_nitelite_mode_enter(){
  setCurrentMode(NITELITE_MODE);
}

void on_nitelite_mode_exit(){

}

void on_off_mode_enter(){
  setCurrentMode(OFF_MODE);
}

void on_off_mode_exit(){

}

// ---- room selection states ---- //
void on_all_enter() {
  setCurrentRoom(ALL_ROOMS);
}

void on_all_exit() {

}

void on_hall_enter() {
  setCurrentRoom(HALL);
}

void on_hall_exit() {

}

void on_living_room_enter() {
  setCurrentRoom(LIVING_ROOM);
}

void on_living_room_exit() {

}

void on_kitchen_enter() {
  setCurrentRoom(KITCHEN);
}

void on_kitchen_exit() {

}

void on_bathroom_enter() {
  setCurrentRoom(BATHROOM);
}

void on_bathroom_exit() {

}

void on_bedroom_enter() {
  setCurrentRoom(BEDROOM);
}

void on_bedroom_exit() {

}

void on_attic_enter() {
  setCurrentRoom(ATTIC);
}

void on_attic_exit() {

}

// Debonce timer
boolean still_bouncing() {
  // If the debounce timer is not running, then we can assume the buttons
  // aren't bouncing because nothing has been pressed recently
  if (timerDebounce == 0) {
    startTimer(timerDebounce);
    return false;
  }

  if (isTimerExpired(timerDebounce, debounceDelay)) {
    clearTimer(timerDebounce);
    startTimer(timerDebounce);
    return false;
  }

  return true;
}

void loop() {
  // do nothing; everything is handled via FSM events.
  // We also don't need to call the ".run_machine" methods of
  // the FSMs as there are no "on_state" handlers or timed transitions
}
<|endoftext|>


<commit_before>/*
    The MIT License (MIT)

    Copyright (c) 2013-2014 Anatoli Steinmark

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

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

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

#include <cassert>
#include <cstring>

#include "ImageImpl.hpp"
#include "octreequant.hpp"

namespace azura {

    //--------------------------------------------------------------
    ImageImpl::ImageImpl(int width, int height, PixelFormat::Enum pf)
        : _width(width)
        , _height(height)
        , _pixelFormat(pf)
        , _pixels(0)
        , _palette(0)
    {
        assert(width > 0);
        assert(height > 0);
        assert(pf >= 0 && pf < PixelFormat::Count);

        PixelFormatDescriptor pfd = GetPixelFormatDescriptor(pf);

        _pixels = new u8[width * height * pfd.bytesPerPixel];

        if (!pfd.isDirectColor) {
            _palette = new RGB[256];
        }
    }

    //--------------------------------------------------------------
    ImageImpl::~ImageImpl()
    {
        delete[] _pixels;

        if (_palette) {
            delete[] _palette;
        }
    }

    //--------------------------------------------------------------
    int
    ImageImpl::getWidth() const
    {
        return _width;
    }

    //--------------------------------------------------------------
    int
    ImageImpl::getHeight() const
    {
        return _height;
    }

    //--------------------------------------------------------------
    PixelFormat::Enum
    ImageImpl::getPixelFormat() const
    {
        return _pixelFormat;
    }

    //--------------------------------------------------------------
    const u8*
    ImageImpl::getPixels() const
    {
        return _pixels;
    }

    //--------------------------------------------------------------
    u8*
    ImageImpl::getPixels()
    {
        return _pixels;
    }

    //--------------------------------------------------------------
    void
    ImageImpl::setPixels(const u8* pixels)
    {
        assert(pixels);

        if (pixels) {
            PixelFormatDescriptor pfd = GetPixelFormatDescriptor(_pixelFormat);
            std::memcpy(_pixels, pixels, _width * _height * pfd.bytesPerPixel);
        }
    }

    //--------------------------------------------------------------
    const RGB*
    ImageImpl::getPalette() const
    {
        return _palette;
    }

    //--------------------------------------------------------------
    RGB*
    ImageImpl::getPalette()
    {
        return _palette;
    }

    //--------------------------------------------------------------
    void
    ImageImpl::setPalette(const RGB palette[256])
    {
        assert(_palette);
        assert(palette);

        if (_palette && palette) {
            std::memcpy(_palette, palette, 256 * sizeof(RGB));
        }
    }

    //--------------------------------------------------------------
    Image::Ptr
    ImageImpl::convert(PixelFormat::Enum pf)
    {
        if (pf < 0 || pf >= PixelFormat::Count) {
            // invalid pixel format requested
            return 0;
        }

        if (_pixelFormat == pf) {
            // already in requested pixel format
            return this;
        }

        PixelFormatDescriptor spfd = GetPixelFormatDescriptor(_pixelFormat);
        PixelFormatDescriptor dpfd = GetPixelFormatDescriptor(pf);

        if (spfd.isDirectColor && dpfd.isDirectColor)
        {
            RefPtr<ImageImpl> result = new ImageImpl(_width, _height, pf);

            u8* sptr = _pixels;
            u8* dptr = result->_pixels;

            for (int i = _width * _height; i > 0; i--) {
                dptr[dpfd.redMask]   = sptr[spfd.redMask];
                dptr[dpfd.greenMask] = sptr[spfd.greenMask];
                dptr[dpfd.blueMask]  = sptr[spfd.blueMask];

                if (dpfd.hasAlpha) {
                    if (spfd.hasAlpha) {
                        dptr[dpfd.alphaMask] = sptr[spfd.alphaMask];
                    } else {
                        dptr[dpfd.alphaMask] = 255;
                    }
                }

                sptr += spfd.bytesPerPixel;
                dptr += dpfd.bytesPerPixel;
            }

            return result;
        }
        else if (!spfd.isDirectColor && dpfd.isDirectColor)
        {
            RefPtr<ImageImpl> result = new ImageImpl(_width, _height, pf);

            u8* sptr = _pixels;
            RGB* splt = _palette;
            u8* dptr = result->_pixels;

            for (int i = _width * _height; i > 0; i--) {
                RGB col = splt[*sptr];

                dptr[dpfd.redMask]   = col.red;
                dptr[dpfd.greenMask] = col.green;
                dptr[dpfd.blueMask]  = col.blue;

                if (dpfd.hasAlpha) {
                    dptr[dpfd.alphaMask] = 255;
                }

                sptr += spfd.bytesPerPixel;
                dptr += dpfd.bytesPerPixel;
            }

            return result;
        }
        else if (spfd.isDirectColor && !dpfd.isDirectColor)
        {
            // color quantization requires source pixels in RGB format
            Image::Ptr rgb_image = convert(PixelFormat::RGB);

            Image::Ptr plt_image = new ImageImpl(_width, _height, pf);
            OctreeQuant((RGB*)rgb_image->getPixels(), _width * _height, plt_image->getPixels(), plt_image->getPalette());

            return plt_image;
        }

        // no suitable conversion available
        return 0;
    }

}
<commit_msg>Zero-initialize image buffers.<commit_after>/*
    The MIT License (MIT)

    Copyright (c) 2013-2014 Anatoli Steinmark

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

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

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

#include <cassert>
#include <cstring>

#include "ImageImpl.hpp"
#include "octreequant.hpp"

namespace azura {

    //--------------------------------------------------------------
    ImageImpl::ImageImpl(int width, int height, PixelFormat::Enum pf)
        : _width(width)
        , _height(height)
        , _pixelFormat(pf)
        , _pixels(0)
        , _palette(0)
    {
        assert(width > 0);
        assert(height > 0);
        assert(pf >= 0 && pf < PixelFormat::Count);

        PixelFormatDescriptor pfd = GetPixelFormatDescriptor(pf);

        _pixels = new u8[width * height * pfd.bytesPerPixel];
        std::memset(_pixels, 0x00, width * height * pfd.bytesPerPixel);

        if (!pfd.isDirectColor) {
            _palette = new RGB[256];
            std::memset(_palette, 0x00, 256 * sizeof(RGB));
        }
    }

    //--------------------------------------------------------------
    ImageImpl::~ImageImpl()
    {
        delete[] _pixels;

        if (_palette) {
            delete[] _palette;
        }
    }

    //--------------------------------------------------------------
    int
    ImageImpl::getWidth() const
    {
        return _width;
    }

    //--------------------------------------------------------------
    int
    ImageImpl::getHeight() const
    {
        return _height;
    }

    //--------------------------------------------------------------
    PixelFormat::Enum
    ImageImpl::getPixelFormat() const
    {
        return _pixelFormat;
    }

    //--------------------------------------------------------------
    const u8*
    ImageImpl::getPixels() const
    {
        return _pixels;
    }

    //--------------------------------------------------------------
    u8*
    ImageImpl::getPixels()
    {
        return _pixels;
    }

    //--------------------------------------------------------------
    void
    ImageImpl::setPixels(const u8* pixels)
    {
        assert(pixels);

        if (pixels) {
            PixelFormatDescriptor pfd = GetPixelFormatDescriptor(_pixelFormat);
            std::memcpy(_pixels, pixels, _width * _height * pfd.bytesPerPixel);
        }
    }

    //--------------------------------------------------------------
    const RGB*
    ImageImpl::getPalette() const
    {
        return _palette;
    }

    //--------------------------------------------------------------
    RGB*
    ImageImpl::getPalette()
    {
        return _palette;
    }

    //--------------------------------------------------------------
    void
    ImageImpl::setPalette(const RGB palette[256])
    {
        assert(_palette);
        assert(palette);

        if (_palette && palette) {
            std::memcpy(_palette, palette, 256 * sizeof(RGB));
        }
    }

    //--------------------------------------------------------------
    Image::Ptr
    ImageImpl::convert(PixelFormat::Enum pf)
    {
        if (pf < 0 || pf >= PixelFormat::Count) {
            // invalid pixel format requested
            return 0;
        }

        if (_pixelFormat == pf) {
            // already in requested pixel format
            return this;
        }

        PixelFormatDescriptor spfd = GetPixelFormatDescriptor(_pixelFormat);
        PixelFormatDescriptor dpfd = GetPixelFormatDescriptor(pf);

        if (spfd.isDirectColor && dpfd.isDirectColor)
        {
            RefPtr<ImageImpl> result = new ImageImpl(_width, _height, pf);

            u8* sptr = _pixels;
            u8* dptr = result->_pixels;

            for (int i = _width * _height; i > 0; i--) {
                dptr[dpfd.redMask]   = sptr[spfd.redMask];
                dptr[dpfd.greenMask] = sptr[spfd.greenMask];
                dptr[dpfd.blueMask]  = sptr[spfd.blueMask];

                if (dpfd.hasAlpha) {
                    if (spfd.hasAlpha) {
                        dptr[dpfd.alphaMask] = sptr[spfd.alphaMask];
                    } else {
                        dptr[dpfd.alphaMask] = 255;
                    }
                }

                sptr += spfd.bytesPerPixel;
                dptr += dpfd.bytesPerPixel;
            }

            return result;
        }
        else if (!spfd.isDirectColor && dpfd.isDirectColor)
        {
            RefPtr<ImageImpl> result = new ImageImpl(_width, _height, pf);

            u8* sptr = _pixels;
            RGB* splt = _palette;
            u8* dptr = result->_pixels;

            for (int i = _width * _height; i > 0; i--) {
                RGB col = splt[*sptr];

                dptr[dpfd.redMask]   = col.red;
                dptr[dpfd.greenMask] = col.green;
                dptr[dpfd.blueMask]  = col.blue;

                if (dpfd.hasAlpha) {
                    dptr[dpfd.alphaMask] = 255;
                }

                sptr += spfd.bytesPerPixel;
                dptr += dpfd.bytesPerPixel;
            }

            return result;
        }
        else if (spfd.isDirectColor && !dpfd.isDirectColor)
        {
            // color quantization requires source pixels in RGB format
            Image::Ptr rgb_image = convert(PixelFormat::RGB);

            Image::Ptr plt_image = new ImageImpl(_width, _height, pf);
            OctreeQuant((RGB*)rgb_image->getPixels(), _width * _height, plt_image->getPixels(), plt_image->getPalette());

            return plt_image;
        }

        // no suitable conversion available
        return 0;
    }

}
<|endoftext|>


<commit_before>#ifndef TESTERDRIVER_H
#define TESTERDRIVER_H

#include <iostream>
#include <string.h>
using namespace std;
#include "wrapperregdriver.h"
#include "TesterWrapper.h"

// uncomment the second line here to enable verbose reg read/writes
//#define __TESTERDRIVER_DEBUG(x) (cout << x << endl)
#define __TESTERDRIVER_DEBUG(x) (0)

// register driver for the Tester platform, using the Chisel-generated C++ model to
// interface with the accelerator model
// note that TesterWrapper.h must be generated for each new accelerator, it is the
// model header not just for the wrapper, but the entire system (wrapper+accel)

class TesterRegDriver : public WrapperRegDriver {
public:
  TesterRegDriver() {m_freePtr = 0;}

  virtual void attach(const char * name) {
    m_inst = new TesterWrapper_t();
    // get # words in the memory
    m_memWords = m_inst->TesterWrapper__mem.length();
    // initialize and reset the model
    m_inst->init();
    reset();
    m_regCount = m_inst->TesterWrapper__io_regFileIF_regCount.to_ulong();
  }

  virtual void detach() { delete m_inst; }

  virtual void copyBufferHostToAccel(void * hostBuffer, void * accelBuffer, unsigned int numBytes) {
    uint64_t accelBufBase = (uint64_t) accelBuffer;
    __TESTERDRIVER_DEBUG("host2accel(" << (uint64_t) hostBuffer << " -> " << accelBufBase << " : " << numBytes << " bytes)");

    if((numBytes % 8 == 0) && (accelBufBase % 8 == 0))
      alignedCopyBufferHostToAccel(hostBuffer, accelBuffer, numBytes);
    else {
      // align base and size
      uint64_t alignedBase = accelBufBase - (accelBufBase % 8);
      uint64_t startDiff = accelBufBase - alignedBase;
      unsigned int alignedSize = (startDiff + numBytes + 7) / 8 * 8;
      // copy containing block into host memory
      char * tmp = new char[alignedSize];
      alignedCopyBufferAccelToHost((void *)alignedBase, (void *) tmp, alignedSize);
      // do host-to-host unaligned copy
      memcpy((void *)&tmp[startDiff], hostBuffer, numBytes);
      // write containing block back to accel memory
      alignedCopyBufferHostToAccel((void *)tmp, (void *)alignedBase, alignedSize);
      delete [] tmp;
    }
  }

  virtual void copyBufferAccelToHost(void * accelBuffer, void * hostBuffer, unsigned int numBytes) {
    uint64_t accelBufBase = (uint64_t) accelBuffer;
    __TESTERDRIVER_DEBUG("accel2host(" << accelBufBase << " -> " << (uint64_t) hostBuffer << " : " << numBytes << " bytes)");

    if((numBytes % 8 == 0) && (accelBufBase % 8 == 0))
      alignedCopyBufferAccelToHost(hostBuffer, accelBuffer, numBytes);
    else {
      // implement unaligned accel-to-host
      // align base and size
      uint64_t alignedBase = accelBufBase - (accelBufBase % 8);
      uint64_t startDiff = accelBufBase - alignedBase;
      unsigned int alignedSize = (startDiff + numBytes + 7) / 8 * 8;
      // copy containing block into host memory
      char * tmp = new char[alignedSize];
      alignedCopyBufferAccelToHost((void *)alignedBase, (void *) tmp, alignedSize);
      // do host-to-host unaligned copy
      memcpy(hostBuffer, (void *)&tmp[startDiff],numBytes);
      delete [] tmp;
    }
  }

  virtual void * allocAccelBuffer(unsigned int numBytes) {
    // all this assumes allocation and mem word size of 8 bytes
    // round requested size to nearest multiple of 8
    unsigned int actualAllocSize = (numBytes + 7) / 8 * 8;
    void * accelBuf = (void *) m_freePtr;
    // update free pointer and sanity check
    m_freePtr += actualAllocSize;
    if(m_freePtr > m_memWords * 8)
      throw "Not enough memory in allocAccelBuffer";
    __TESTERDRIVER_DEBUG("allocAccelBuffer(" << numBytes << ", alloc " << actualAllocSize <<") = " << (uint64_t) accelBuf);

    return accelBuf;
  }

  // register access methods for the platform wrapper
  virtual void writeReg(unsigned int regInd, AccelReg regValue) {
    __TESTERDRIVER_DEBUG("writeReg(" << regInd << ", " << regValue  << ") ");

    m_inst->TesterWrapper__io_regFileIF_cmd_bits_writeData = regValue;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_write  = 1;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_regID = regInd;
    m_inst->TesterWrapper__io_regFileIF_cmd_valid = 1;
    step();
    m_inst->TesterWrapper__io_regFileIF_cmd_valid = 0;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_write = 0;
    step(5);  // extra delay on write completion to be realistic
  }

  virtual AccelReg readReg(unsigned int regInd) {
    AccelReg ret;

    m_inst->TesterWrapper__io_regFileIF_cmd_bits_regID = regInd;
    m_inst->TesterWrapper__io_regFileIF_cmd_valid = 1;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_read = 1;
    step(); // don't actually need 1 cycle, regfile reads are combinational

    if(!m_inst->TesterWrapper__io_regFileIF_readData_valid.to_bool())
      throw "Could not read register";

    m_inst->TesterWrapper__io_regFileIF_cmd_valid = 0;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_read = 0;

    ret = m_inst->TesterWrapper__io_regFileIF_readData_bits.to_ulong();

    __TESTERDRIVER_DEBUG("readReg(" << regInd << ") = " << ret);

    step(5);  // extra delay on read completion to be realistic

    return ret;
  }

  void printAllRegs() {
    for(unsigned int i = 0; i < m_regCount; i++)  {
        AccelReg val = readReg(i);
        cout << "Reg " << i << " = " << val << " (0x" << hex << val << dec << ")" << endl;
      }

  }

protected:
  TesterWrapper_t * m_inst;
  unsigned int m_memWords;
  unsigned int m_regCount;
  uint64_t m_freePtr;

  void reset() {
    m_inst->clock(1);
    m_inst->clock(0);
    // Chisel c++ backend requires this workaround to get out the correct values
    m_inst->clock_lo(0);
  }

  void step(int n = 1) {
    for(int i = 0; i < n; i++) {
      m_inst->clock(0);
      // Chisel c++ backend requires this workaround to get out the correct values
      m_inst->clock_lo(0);
    }
  }

  void memWrite(uint64_t addr, uint64_t value) {
    m_inst->TesterWrapper__io_memAddr = addr;
    m_inst->TesterWrapper__io_memWriteData = value;
    m_inst->TesterWrapper__io_memWriteEn = 1;
    step();
    m_inst->TesterWrapper__io_memWriteEn = 0;
  }

  uint64_t memRead(uint64_t addr) {
    m_inst->TesterWrapper__io_memAddr = addr;
    step();
    uint64_t ret = m_inst->TesterWrapper__io_memReadData[0];
    return ret;
  }

  // "aligned" copy functions, where accel ptr start and size are guaranteed to be 8-aligned
  void alignedCopyBufferHostToAccel(void * hostBuffer, void * accelBuffer, unsigned int numBytes) {
    uint64_t * host_buf = (uint64_t *) hostBuffer;
    uint64_t accelBufBase = (uint64_t) accelBuffer;
    for(unsigned int i = 0; i < numBytes/8; i++)
        memWrite(accelBufBase + i*8, host_buf[i]);
  }

  void alignedCopyBufferAccelToHost(void * accelBuffer, void * hostBuffer, unsigned int numBytes) {
    uint64_t accelBufBase = (uint64_t) accelBuffer;
    uint64_t * readBuf = (uint64_t *) hostBuffer;
    for(unsigned int i = 0; i < numBytes/8; i++)
      readBuf[i] = memRead(accelBufBase + i*8);
  }
};

#endif
<commit_msg>TesterDriver bugfix: src-dest in copy switched places<commit_after>#ifndef TESTERDRIVER_H
#define TESTERDRIVER_H

#include <iostream>
#include <string.h>
using namespace std;
#include "wrapperregdriver.h"
#include "TesterWrapper.h"

// uncomment the second line here to enable verbose reg read/writes
//#define __TESTERDRIVER_DEBUG(x) (cout << x << endl)
#define __TESTERDRIVER_DEBUG(x) (0)

// register driver for the Tester platform, using the Chisel-generated C++ model to
// interface with the accelerator model
// note that TesterWrapper.h must be generated for each new accelerator, it is the
// model header not just for the wrapper, but the entire system (wrapper+accel)

class TesterRegDriver : public WrapperRegDriver {
public:
  TesterRegDriver() {m_freePtr = 0;}

  virtual void attach(const char * name) {
    m_inst = new TesterWrapper_t();
    // get # words in the memory
    m_memWords = m_inst->TesterWrapper__mem.length();
    // initialize and reset the model
    m_inst->init();
    reset();
    m_regCount = m_inst->TesterWrapper__io_regFileIF_regCount.to_ulong();
  }

  virtual void detach() { delete m_inst; }

  virtual void copyBufferHostToAccel(void * hostBuffer, void * accelBuffer, unsigned int numBytes) {
    uint64_t accelBufBase = (uint64_t) accelBuffer;
    __TESTERDRIVER_DEBUG("host2accel(" << (uint64_t) hostBuffer << " -> " << accelBufBase << " : " << numBytes << " bytes)");

    if((numBytes % 8 == 0) && (accelBufBase % 8 == 0))
      alignedCopyBufferHostToAccel(hostBuffer, accelBuffer, numBytes);
    else {
      // align base and size
      uint64_t alignedBase = accelBufBase - (accelBufBase % 8);
      uint64_t startDiff = accelBufBase - alignedBase;
      unsigned int alignedSize = (startDiff + numBytes + 7) / 8 * 8;
      // copy containing block into host memory
      char * tmp = new char[alignedSize];
      alignedCopyBufferAccelToHost((void *)alignedBase, (void *) tmp, alignedSize);
      // do host-to-host unaligned copy
      memcpy((void *)&tmp[startDiff], hostBuffer, numBytes);
      // write containing block back to accel memory
      alignedCopyBufferHostToAccel((void *)tmp, (void *)alignedBase, alignedSize);
      delete [] tmp;
    }
  }

  virtual void copyBufferAccelToHost(void * accelBuffer, void * hostBuffer, unsigned int numBytes) {
    uint64_t accelBufBase = (uint64_t) accelBuffer;
    __TESTERDRIVER_DEBUG("accel2host(" << accelBufBase << " -> " << (uint64_t) hostBuffer << " : " << numBytes << " bytes)");

    if((numBytes % 8 == 0) && (accelBufBase % 8 == 0))
      alignedCopyBufferAccelToHost(accelBuffer, hostBuffer, numBytes);
    else {
      // implement unaligned accel-to-host
      // align base and size
      uint64_t alignedBase = accelBufBase - (accelBufBase % 8);
      uint64_t startDiff = accelBufBase - alignedBase;
      unsigned int alignedSize = (startDiff + numBytes + 7) / 8 * 8;
      // copy containing block into host memory
      char * tmp = new char[alignedSize];
      alignedCopyBufferAccelToHost((void *)alignedBase, (void *) tmp, alignedSize);
      // do host-to-host unaligned copy
      memcpy(hostBuffer, (void *)&tmp[startDiff],numBytes);
      delete [] tmp;
    }
  }

  virtual void * allocAccelBuffer(unsigned int numBytes) {
    // all this assumes allocation and mem word size of 8 bytes
    // round requested size to nearest multiple of 8
    unsigned int actualAllocSize = (numBytes + 7) / 8 * 8;
    void * accelBuf = (void *) m_freePtr;
    // update free pointer and sanity check
    m_freePtr += actualAllocSize;
    if(m_freePtr > m_memWords * 8)
      throw "Not enough memory in allocAccelBuffer";
    __TESTERDRIVER_DEBUG("allocAccelBuffer(" << numBytes << ", alloc " << actualAllocSize <<") = " << (uint64_t) accelBuf);

    return accelBuf;
  }

  // register access methods for the platform wrapper
  virtual void writeReg(unsigned int regInd, AccelReg regValue) {
    __TESTERDRIVER_DEBUG("writeReg(" << regInd << ", " << regValue  << ") ");

    m_inst->TesterWrapper__io_regFileIF_cmd_bits_writeData = regValue;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_write  = 1;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_regID = regInd;
    m_inst->TesterWrapper__io_regFileIF_cmd_valid = 1;
    step();
    m_inst->TesterWrapper__io_regFileIF_cmd_valid = 0;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_write = 0;
    step(5);  // extra delay on write completion to be realistic
  }

  virtual AccelReg readReg(unsigned int regInd) {
    AccelReg ret;

    m_inst->TesterWrapper__io_regFileIF_cmd_bits_regID = regInd;
    m_inst->TesterWrapper__io_regFileIF_cmd_valid = 1;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_read = 1;
    step(); // don't actually need 1 cycle, regfile reads are combinational

    if(!m_inst->TesterWrapper__io_regFileIF_readData_valid.to_bool())
      throw "Could not read register";

    m_inst->TesterWrapper__io_regFileIF_cmd_valid = 0;
    m_inst->TesterWrapper__io_regFileIF_cmd_bits_read = 0;

    ret = m_inst->TesterWrapper__io_regFileIF_readData_bits.to_ulong();

    __TESTERDRIVER_DEBUG("readReg(" << regInd << ") = " << ret);

    step(5);  // extra delay on read completion to be realistic

    return ret;
  }

  void printAllRegs() {
    for(unsigned int i = 0; i < m_regCount; i++)  {
        AccelReg val = readReg(i);
        cout << "Reg " << i << " = " << val << " (0x" << hex << val << dec << ")" << endl;
      }

  }

protected:
  TesterWrapper_t * m_inst;
  unsigned int m_memWords;
  unsigned int m_regCount;
  uint64_t m_freePtr;

  void reset() {
    m_inst->clock(1);
    m_inst->clock(0);
    // Chisel c++ backend requires this workaround to get out the correct values
    m_inst->clock_lo(0);
  }

  void step(int n = 1) {
    for(int i = 0; i < n; i++) {
      m_inst->clock(0);
      // Chisel c++ backend requires this workaround to get out the correct values
      m_inst->clock_lo(0);
    }
  }

  void memWrite(uint64_t addr, uint64_t value) {
    m_inst->TesterWrapper__io_memAddr = addr;
    m_inst->TesterWrapper__io_memWriteData = value;
    m_inst->TesterWrapper__io_memWriteEn = 1;
    step();
    m_inst->TesterWrapper__io_memWriteEn = 0;
  }

  uint64_t memRead(uint64_t addr) {
    m_inst->TesterWrapper__io_memAddr = addr;
    step();
    uint64_t ret = m_inst->TesterWrapper__io_memReadData[0];
    return ret;
  }

  // "aligned" copy functions, where accel ptr start and size are guaranteed to be 8-aligned
  void alignedCopyBufferHostToAccel(void * hostBuffer, void * accelBuffer, unsigned int numBytes) {
    uint64_t * host_buf = (uint64_t *) hostBuffer;
    uint64_t accelBufBase = (uint64_t) accelBuffer;
    for(unsigned int i = 0; i < numBytes/8; i++)
        memWrite(accelBufBase + i*8, host_buf[i]);
  }

  void alignedCopyBufferAccelToHost(void * accelBuffer, void * hostBuffer, unsigned int numBytes) {
    uint64_t accelBufBase = (uint64_t) accelBuffer;
    uint64_t * readBuf = (uint64_t *) hostBuffer;
    for(unsigned int i = 0; i < numBytes/8; i++)
      readBuf[i] = memRead(accelBufBase + i*8);
  }
};

#endif
<|endoftext|>