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

// This file contains the implementation of the command buffer helper class.

#include "../client/cmd_buffer_helper.h"
#include "../common/command_buffer.h"
#include "../common/trace_event.h"

namespace gpu {

CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer)
    : command_buffer_(command_buffer),
      entries_(NULL),
      total_entry_count_(0),
      usable_entry_count_(0),
      token_(0),
      last_token_read_(-1),
      get_(0),
      put_(0),
      last_put_sent_(0) {
}

bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
  ring_buffer_ = command_buffer_->GetRingBuffer();
  if (!ring_buffer_.ptr)
    return false;

  CommandBuffer::State state = command_buffer_->GetState();
  entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr);
  int32 num_ring_buffer_entries = ring_buffer_size / sizeof(CommandBufferEntry);
  if (num_ring_buffer_entries > state.num_entries) {
    return false;
  }

  const int32 kJumpEntries =
      sizeof(cmd::Jump) / sizeof(*entries_);  // NOLINT

  total_entry_count_ = num_ring_buffer_entries;
  usable_entry_count_ = total_entry_count_ - kJumpEntries;
  put_ = state.put_offset;
  SynchronizeState(state);
  return true;
}

CommandBufferHelper::~CommandBufferHelper() {
}

bool CommandBufferHelper::FlushSync() {
  last_put_sent_ = put_;
  CommandBuffer::State state = command_buffer_->FlushSync(put_, get_);
  SynchronizeState(state);
  return state.error == error::kNoError;
}

void CommandBufferHelper::Flush() {
  last_put_sent_ = put_;
  command_buffer_->Flush(put_);
}

// Calls Flush() and then waits until the buffer is empty. Break early if the
// error is set.
bool CommandBufferHelper::Finish() {
  TRACE_EVENT0("gpu", "CommandBufferHelper::Finish");
  do {
    // Do not loop forever if the flush fails, meaning the command buffer reader
    // has shutdown.
    if (!FlushSync())
      return false;
  } while (put_ != get_);

  return true;
}

// Inserts a new token into the command stream. It uses an increasing value
// scheme so that we don't lose tokens (a token has passed if the current token
// value is higher than that token). Calls Finish() if the token value wraps,
// which will be rare.
int32 CommandBufferHelper::InsertToken() {
  // Increment token as 31-bit integer. Negative values are used to signal an
  // error.
  token_ = (token_ + 1) & 0x7FFFFFFF;
  cmd::SetToken& cmd = GetCmdSpace<cmd::SetToken>();
  cmd.Init(token_);
  if (token_ == 0) {
    TRACE_EVENT0("gpu", "CommandBufferHelper::InsertToken(wrapped)");
    // we wrapped
    Finish();
    GPU_DCHECK_EQ(token_, last_token_read_);
  }
  return token_;
}

// Waits until the current token value is greater or equal to the value passed
// in argument.
void CommandBufferHelper::WaitForToken(int32 token) {
  TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForToken");
  // Return immediately if corresponding InsertToken failed.
  if (token < 0)
    return;
  if (token > token_) return;  // we wrapped
  while (last_token_read_ < token) {
    if (get_ == put_) {
      GPU_LOG(FATAL) << "Empty command buffer while waiting on a token.";
      return;
    }
    // Do not loop forever if the flush fails, meaning the command buffer reader
    // has shutdown.
    if (!FlushSync())
      return;
  }
}

void CommandBufferHelper::YieldScheduler() {
  cmd::YieldScheduler& cmd = GetCmdSpace<cmd::YieldScheduler>();
  cmd.Init();
}

// Waits for available entries, basically waiting until get >= put + count + 1.
// It actually waits for contiguous entries, so it may need to wrap the buffer
// around, adding a jump. Thus this function may change the value of put_. The
// function will return early if an error occurs, in which case the available
// space may not be available.
void CommandBufferHelper::WaitForAvailableEntries(int32 count) {
  GPU_CHECK(count < usable_entry_count_);
  if (put_ + count > usable_entry_count_) {
    // There's not enough room between the current put and the end of the
    // buffer, so we need to wrap. We will add a jump back to the start, but we
    // need to make sure get wraps first, actually that get is 1 or more (since
    // put will wrap to 0 after we add the jump).
    GPU_DCHECK_LE(1, put_);
    if (get_ > put_ || get_ == 0) {
      TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries");
      while (get_ > put_ || get_ == 0) {
        // Do not loop forever if the flush fails, meaning the command buffer
        // reader has shutdown.
        if (!FlushSync())
          return;
      }
    }
    // Insert a jump back to the beginning.
    cmd::Jump::Set(&entries_[put_], 0);
    put_ = 0;
  }
  if (AvailableEntries() < count) {
    TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries1");
    while (AvailableEntries() < count) {
      // Do not loop forever if the flush fails, meaning the command buffer
      // reader has shutdown.
      if (!FlushSync())
        return;
    }
  }
  // Force a flush if the buffer is getting half full, or even earlier if the
  // reader is known to be idle.
  int32 pending =
      (put_ + usable_entry_count_ - last_put_sent_) % usable_entry_count_;
  int32 limit = usable_entry_count_ / ((get_ == last_put_sent_) ? 16 : 2);
  if (pending > limit) {
    Flush();
  }
}

CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) {
  WaitForAvailableEntries(entries);
  CommandBufferEntry* space = &entries_[put_];
  put_ += entries;
  GPU_DCHECK_LE(put_, usable_entry_count_);
  if (put_ == usable_entry_count_) {
    cmd::Jump::Set(&entries_[put_], 0);
    put_ = 0;
  }
  return space;
}

error::Error CommandBufferHelper::GetError() {
  CommandBuffer::State state = command_buffer_->GetState();
  SynchronizeState(state);
  return static_cast<error::Error>(state.error);
}

void CommandBufferHelper::SynchronizeState(CommandBuffer::State state) {
  get_ = state.get_offset;
  last_token_read_ = state.token;
}

}  // namespace gpu
<commit_msg>Changed CHECK to DCHECK in cmd_buffer_helper.cc.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains the implementation of the command buffer helper class.

#include "../client/cmd_buffer_helper.h"
#include "../common/command_buffer.h"
#include "../common/trace_event.h"

namespace gpu {

CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer)
    : command_buffer_(command_buffer),
      entries_(NULL),
      total_entry_count_(0),
      usable_entry_count_(0),
      token_(0),
      last_token_read_(-1),
      get_(0),
      put_(0),
      last_put_sent_(0) {
}

bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
  ring_buffer_ = command_buffer_->GetRingBuffer();
  if (!ring_buffer_.ptr)
    return false;

  CommandBuffer::State state = command_buffer_->GetState();
  entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr);
  int32 num_ring_buffer_entries = ring_buffer_size / sizeof(CommandBufferEntry);
  if (num_ring_buffer_entries > state.num_entries) {
    return false;
  }

  const int32 kJumpEntries =
      sizeof(cmd::Jump) / sizeof(*entries_);  // NOLINT

  total_entry_count_ = num_ring_buffer_entries;
  usable_entry_count_ = total_entry_count_ - kJumpEntries;
  put_ = state.put_offset;
  SynchronizeState(state);
  return true;
}

CommandBufferHelper::~CommandBufferHelper() {
}

bool CommandBufferHelper::FlushSync() {
  last_put_sent_ = put_;
  CommandBuffer::State state = command_buffer_->FlushSync(put_, get_);
  SynchronizeState(state);
  return state.error == error::kNoError;
}

void CommandBufferHelper::Flush() {
  last_put_sent_ = put_;
  command_buffer_->Flush(put_);
}

// Calls Flush() and then waits until the buffer is empty. Break early if the
// error is set.
bool CommandBufferHelper::Finish() {
  TRACE_EVENT0("gpu", "CommandBufferHelper::Finish");
  do {
    // Do not loop forever if the flush fails, meaning the command buffer reader
    // has shutdown.
    if (!FlushSync())
      return false;
  } while (put_ != get_);

  return true;
}

// Inserts a new token into the command stream. It uses an increasing value
// scheme so that we don't lose tokens (a token has passed if the current token
// value is higher than that token). Calls Finish() if the token value wraps,
// which will be rare.
int32 CommandBufferHelper::InsertToken() {
  // Increment token as 31-bit integer. Negative values are used to signal an
  // error.
  token_ = (token_ + 1) & 0x7FFFFFFF;
  cmd::SetToken& cmd = GetCmdSpace<cmd::SetToken>();
  cmd.Init(token_);
  if (token_ == 0) {
    TRACE_EVENT0("gpu", "CommandBufferHelper::InsertToken(wrapped)");
    // we wrapped
    Finish();
    GPU_DCHECK_EQ(token_, last_token_read_);
  }
  return token_;
}

// Waits until the current token value is greater or equal to the value passed
// in argument.
void CommandBufferHelper::WaitForToken(int32 token) {
  TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForToken");
  // Return immediately if corresponding InsertToken failed.
  if (token < 0)
    return;
  if (token > token_) return;  // we wrapped
  while (last_token_read_ < token) {
    if (get_ == put_) {
      GPU_LOG(FATAL) << "Empty command buffer while waiting on a token.";
      return;
    }
    // Do not loop forever if the flush fails, meaning the command buffer reader
    // has shutdown.
    if (!FlushSync())
      return;
  }
}

void CommandBufferHelper::YieldScheduler() {
  cmd::YieldScheduler& cmd = GetCmdSpace<cmd::YieldScheduler>();
  cmd.Init();
}

// Waits for available entries, basically waiting until get >= put + count + 1.
// It actually waits for contiguous entries, so it may need to wrap the buffer
// around, adding a jump. Thus this function may change the value of put_. The
// function will return early if an error occurs, in which case the available
// space may not be available.
void CommandBufferHelper::WaitForAvailableEntries(int32 count) {
  GPU_DCHECK(count < usable_entry_count_);
  if (put_ + count > usable_entry_count_) {
    // There's not enough room between the current put and the end of the
    // buffer, so we need to wrap. We will add a jump back to the start, but we
    // need to make sure get wraps first, actually that get is 1 or more (since
    // put will wrap to 0 after we add the jump).
    GPU_DCHECK_LE(1, put_);
    if (get_ > put_ || get_ == 0) {
      TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries");
      while (get_ > put_ || get_ == 0) {
        // Do not loop forever if the flush fails, meaning the command buffer
        // reader has shutdown.
        if (!FlushSync())
          return;
      }
    }
    // Insert a jump back to the beginning.
    cmd::Jump::Set(&entries_[put_], 0);
    put_ = 0;
  }
  if (AvailableEntries() < count) {
    TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries1");
    while (AvailableEntries() < count) {
      // Do not loop forever if the flush fails, meaning the command buffer
      // reader has shutdown.
      if (!FlushSync())
        return;
    }
  }
  // Force a flush if the buffer is getting half full, or even earlier if the
  // reader is known to be idle.
  int32 pending =
      (put_ + usable_entry_count_ - last_put_sent_) % usable_entry_count_;
  int32 limit = usable_entry_count_ / ((get_ == last_put_sent_) ? 16 : 2);
  if (pending > limit) {
    Flush();
  }
}

CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) {
  WaitForAvailableEntries(entries);
  CommandBufferEntry* space = &entries_[put_];
  put_ += entries;
  GPU_DCHECK_LE(put_, usable_entry_count_);
  if (put_ == usable_entry_count_) {
    cmd::Jump::Set(&entries_[put_], 0);
    put_ = 0;
  }
  return space;
}

error::Error CommandBufferHelper::GetError() {
  CommandBuffer::State state = command_buffer_->GetState();
  SynchronizeState(state);
  return static_cast<error::Error>(state.error);
}

void CommandBufferHelper::SynchronizeState(CommandBuffer::State state) {
  get_ = state.get_offset;
  last_token_read_ = state.token;
}

}  // namespace gpu
<|endoftext|>


<commit_before>/* conduitConfigWizard.cc                KPilot
**
** Copyright (C) 2004 by Reinhold Kainhofer
**
** A simple configuration wizard.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

static const char *conduitconfigdialog_id =
	"$Id$";

//#include "options.h"

#include <qpushbutton.h>
#include <qbuttongroup.h>
#include <qcheckbox.h>
#include <qlineedit.h>

#include <kmessagebox.h>
#include <kglobal.h>
#include <klocale.h>
#include <kconfigskeleton.h>

#include "kpilotConfig.h"
#include "options.h"

#include "kpilotConfigWizard_base1.h"
#include "kpilotConfigWizard_base2.h"
#include "kpilotConfigWizard_base3.h"
#include "kpilotConfigWizard_address.h"
#include "kpilotConfigWizard_notes.h"
#include "kpilotConfigWizard_vcal.h"

#include "kpilotConfigWizard.moc"
#include "kpilotProbeDialog.h"

ConfigWizard::ConfigWizard(QWidget *parent, const char *n, int m) :
	KWizard(parent, n),
	fMode((Mode)m)
{
//	page1=new ConfigWizard_base1(this);
//	addPage( page1, i18n("Select Connection Type") );
	page2=new ConfigWizard_base2(this);
	addPage( page2, i18n("Pilot Info") );
	page3=new ConfigWizard_base3(this);
	addPage( page3, i18n("Application to Sync With") );
	setFinishEnabled( page3, true );

	connect( page2->fProbeButton, SIGNAL( pressed() ),
		this, SLOT( probeHandheld() ) );

	KPilotSettings::self()->readConfig();
	page2->fUserName->setText( KPilotSettings::userName() );
	page2->fDeviceName->setText( KPilotSettings::pilotDevice() );
	page2->fPilotRunningPermanently->setChecked( KPilotSettings::startDaemonAtLogin() );
}

ConfigWizard::~ConfigWizard()
{
}

void ConfigWizard::accept()
{
	FUNCTIONSETUP;
	QString username( page2->fUserName->text() );
	QString devicename( page2->fDeviceName->text() );
//	int devicetype( page1->fConnectionType->selectedId() );
	enum eSyncApp {
		eAppKDE=0,
		eAppKontact,
		eAppEvolution,
		eAppNone
	} app;
	app=(eSyncApp)( page3->fAppType->selectedId() );
	bool keepPermanently( page2->fPilotRunningPermanently->isChecked() );
#ifdef DEBUG
	DEBUGCONDUIT<<fname<<"Keep permanently: "<<keepPermanently<<endl;
#endif

	KPilotSettings::setPilotDevice( devicename );
	KPilotSettings::setUserName(username);
//	KPilotSettings::setEncoding("iso 8859-15");
	KPilotSettings::setDockDaemon( true );
	KPilotSettings::setKillDaemonAtExit( !keepPermanently);
	KPilotSettings::setQuitAfterSync( !keepPermanently );
	KPilotSettings::setStartDaemonAtLogin( keepPermanently );
	KPilotSettings::setSyncType(0);
	KPilotSettings::setFullSyncOnPCChange( true );
	KPilotSettings::setConflictResolution(0);

	KPilotWizard_vcalConfig*calendarConfig = new KPilotWizard_vcalConfig("Calendar");
	KPilotWizard_vcalConfig*todoConfig = new KPilotWizard_vcalConfig("ToDo");
	KPilotWizard_addressConfig*addressConfig = new KPilotWizard_addressConfig();
	KPilotWizard_notesConfig*notesConfig = new KPilotWizard_notesConfig();
	addressConfig->readConfig();
	notesConfig->readConfig();
	todoConfig->readConfig();
	calendarConfig->readConfig();

	QStringList conduits = KPilotSettings::installedConduits();
	int version(0);
#define APPEND_CONDUIT(a) if (!conduits.contains(a)) conduits.append(a)
	QString applicationName(i18n("general KDE-PIM"));
	APPEND_CONDUIT("internal_fileinstall");
	APPEND_CONDUIT("todo-conduit");
	APPEND_CONDUIT("vcal-conduit");
	switch (app) {
		case eAppEvolution:
			applicationName=i18n("Gnome's PIM suite", "Evolution");

			// TODO: Once the Evolution abook resource is finished, enable it...
			conduits.remove("abbrowser_conduit");
			// addressConfig->setDefaults();
			// addressConfig->setAddressbookType( KPilotWizard_addressConfig::eAbookResource );
			//// addressConfig->revertToDefault("ArchiveDeleted");
			//// addressConfig->revertToDefault("ConflictResolution");

			// nothing to do for knotes conduit yet (evolution doesn't have notes)
			conduits.remove("knotes-conduit");

			// the vcalconduits use the same config file, so set the correct groups
			version = calendarConfig->conduitVersion();
			calendarConfig->setDefaults();
			calendarConfig->setCalendarType( KPilotWizard_vcalConfig::eCalendarLocal );
			calendarConfig->setCalendarFile( "$HOME/evolution/local/Calendar/calendar.ics" );
			calendarConfig->setConduitVersion( version );
			version = todoConfig->conduitVersion();
			todoConfig->setDefaults();
			todoConfig->setCalendarType( KPilotWizard_vcalConfig::eCalendarLocal );
			todoConfig->setCalendarFile( "$HOME/evolution/local/Tasks/tasks.ics" );
			todoConfig->setConduitVersion( version );

			KMessageBox::information(this, i18n("KPilot cannot yet synchronize the addressbook with Evolution, so the addressbook conduit was disabled.\nWhen syncing the calendar or todo list using KPilot please quit Evolution before the sync, otherwise you will lose data."), i18n("Restrictions with Evolution"));
			break;
		case eAppNone:
			conduits.clear();
			APPEND_CONDUIT("internal_fileinstall");
			applicationName=i18n("Kpilot will sync with nothing","nothing (it will backup only)");
			break;
		case eAppKontact:
			applicationName=i18n("KDE's PIM suite", "Kontact");
		case eAppKDE:
		default:
			APPEND_CONDUIT("knotes-conduit");
			APPEND_CONDUIT("abbrowser_conduit");
			// Set to the stdaddressbook, reset others to defaults
			addressConfig->setAddressbookType( KPilotWizard_addressConfig::eAbookResource );
			addressConfig->setArchiveDeleted( true );
			addressConfig->setConflictResolution( -1 );
			// nothing to do for knotes conduit yet
			// notesConfig->set...
			// the vcalconduits use the same config file, so set the correct groups
			int version = calendarConfig->conduitVersion();
			calendarConfig->setDefaults();
			calendarConfig->setCalendarType( KPilotWizard_vcalConfig::eCalendarResource );
			calendarConfig->setConduitVersion( version );
			version = todoConfig->conduitVersion();
			todoConfig->setDefaults();
			todoConfig->setCalendarType( KPilotWizard_vcalConfig::eCalendarResource );
			todoConfig->setConduitVersion( version );
			break;
	}
	addressConfig->writeConfig();
	notesConfig->writeConfig();
	todoConfig->writeConfig();
	calendarConfig->writeConfig();

	KPILOT_DELETE(addressConfig);
	KPILOT_DELETE(notesConfig);
	KPILOT_DELETE(todoConfig);
	KPILOT_DELETE(calendarConfig);

	KPilotSettings::setInstalledConduits( conduits );
#undef APPEND_CONDUIT

	QString finishMessage = i18n("KPilot is now configured to sync with %1.").arg(applicationName);
	if (fMode == InDialog)
	{
		finishMessage.append(CSL1("\n"));
		finishMessage.append(i18n(
			"The remaining options in the config dialog are advanced options and can "
			"be used to fine-tune KPilot."));
	}

	KMessageBox::information(this, finishMessage,
		i18n("Automatic Configuration Finished"));
	KPilotSettings::self()->writeConfig();
	QDialog::accept();
}

void ConfigWizard::probeHandheld()
{
	ProbeDialog *probeDialog = new ProbeDialog( this );
	if ( probeDialog->exec() && probeDialog->detected() ) {
		page2->fUserName->setText( probeDialog->userName() );
		page2->fDeviceName->setText( probeDialog->device() );
	}
	KPILOT_DELETE(probeDialog);
}

<commit_msg>This file doesn't exist anymore<commit_after>/* conduitConfigWizard.cc                KPilot
**
** Copyright (C) 2004 by Reinhold Kainhofer
**
** A simple configuration wizard.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

static const char *conduitconfigdialog_id =
	"$Id$";

//#include "options.h"

#include <qpushbutton.h>
#include <qbuttongroup.h>
#include <qcheckbox.h>
#include <qlineedit.h>

#include <kmessagebox.h>
#include <kglobal.h>
#include <klocale.h>
#include <kconfigskeleton.h>

#include "kpilotConfig.h"
#include "options.h"

#include "kpilotConfigWizard_base2.h"
#include "kpilotConfigWizard_base3.h"
#include "kpilotConfigWizard_address.h"
#include "kpilotConfigWizard_notes.h"
#include "kpilotConfigWizard_vcal.h"

#include "kpilotConfigWizard.moc"
#include "kpilotProbeDialog.h"

ConfigWizard::ConfigWizard(QWidget *parent, const char *n, int m) :
	KWizard(parent, n),
	fMode((Mode)m)
{
//	page1=new ConfigWizard_base1(this);
//	addPage( page1, i18n("Select Connection Type") );
	page2=new ConfigWizard_base2(this);
	addPage( page2, i18n("Pilot Info") );
	page3=new ConfigWizard_base3(this);
	addPage( page3, i18n("Application to Sync With") );
	setFinishEnabled( page3, true );

	connect( page2->fProbeButton, SIGNAL( pressed() ),
		this, SLOT( probeHandheld() ) );

	KPilotSettings::self()->readConfig();
	page2->fUserName->setText( KPilotSettings::userName() );
	page2->fDeviceName->setText( KPilotSettings::pilotDevice() );
	page2->fPilotRunningPermanently->setChecked( KPilotSettings::startDaemonAtLogin() );
}

ConfigWizard::~ConfigWizard()
{
}

void ConfigWizard::accept()
{
	FUNCTIONSETUP;
	QString username( page2->fUserName->text() );
	QString devicename( page2->fDeviceName->text() );
//	int devicetype( page1->fConnectionType->selectedId() );
	enum eSyncApp {
		eAppKDE=0,
		eAppKontact,
		eAppEvolution,
		eAppNone
	} app;
	app=(eSyncApp)( page3->fAppType->selectedId() );
	bool keepPermanently( page2->fPilotRunningPermanently->isChecked() );
#ifdef DEBUG
	DEBUGCONDUIT<<fname<<"Keep permanently: "<<keepPermanently<<endl;
#endif

	KPilotSettings::setPilotDevice( devicename );
	KPilotSettings::setUserName(username);
//	KPilotSettings::setEncoding("iso 8859-15");
	KPilotSettings::setDockDaemon( true );
	KPilotSettings::setKillDaemonAtExit( !keepPermanently);
	KPilotSettings::setQuitAfterSync( !keepPermanently );
	KPilotSettings::setStartDaemonAtLogin( keepPermanently );
	KPilotSettings::setSyncType(0);
	KPilotSettings::setFullSyncOnPCChange( true );
	KPilotSettings::setConflictResolution(0);

	KPilotWizard_vcalConfig*calendarConfig = new KPilotWizard_vcalConfig("Calendar");
	KPilotWizard_vcalConfig*todoConfig = new KPilotWizard_vcalConfig("ToDo");
	KPilotWizard_addressConfig*addressConfig = new KPilotWizard_addressConfig();
	KPilotWizard_notesConfig*notesConfig = new KPilotWizard_notesConfig();
	addressConfig->readConfig();
	notesConfig->readConfig();
	todoConfig->readConfig();
	calendarConfig->readConfig();

	QStringList conduits = KPilotSettings::installedConduits();
	int version(0);
#define APPEND_CONDUIT(a) if (!conduits.contains(a)) conduits.append(a)
	QString applicationName(i18n("general KDE-PIM"));
	APPEND_CONDUIT("internal_fileinstall");
	APPEND_CONDUIT("todo-conduit");
	APPEND_CONDUIT("vcal-conduit");
	switch (app) {
		case eAppEvolution:
			applicationName=i18n("Gnome's PIM suite", "Evolution");

			// TODO: Once the Evolution abook resource is finished, enable it...
			conduits.remove("abbrowser_conduit");
			// addressConfig->setDefaults();
			// addressConfig->setAddressbookType( KPilotWizard_addressConfig::eAbookResource );
			//// addressConfig->revertToDefault("ArchiveDeleted");
			//// addressConfig->revertToDefault("ConflictResolution");

			// nothing to do for knotes conduit yet (evolution doesn't have notes)
			conduits.remove("knotes-conduit");

			// the vcalconduits use the same config file, so set the correct groups
			version = calendarConfig->conduitVersion();
			calendarConfig->setDefaults();
			calendarConfig->setCalendarType( KPilotWizard_vcalConfig::eCalendarLocal );
			calendarConfig->setCalendarFile( "$HOME/evolution/local/Calendar/calendar.ics" );
			calendarConfig->setConduitVersion( version );
			version = todoConfig->conduitVersion();
			todoConfig->setDefaults();
			todoConfig->setCalendarType( KPilotWizard_vcalConfig::eCalendarLocal );
			todoConfig->setCalendarFile( "$HOME/evolution/local/Tasks/tasks.ics" );
			todoConfig->setConduitVersion( version );

			KMessageBox::information(this, i18n("KPilot cannot yet synchronize the addressbook with Evolution, so the addressbook conduit was disabled.\nWhen syncing the calendar or todo list using KPilot please quit Evolution before the sync, otherwise you will lose data."), i18n("Restrictions with Evolution"));
			break;
		case eAppNone:
			conduits.clear();
			APPEND_CONDUIT("internal_fileinstall");
			applicationName=i18n("Kpilot will sync with nothing","nothing (it will backup only)");
			break;
		case eAppKontact:
			applicationName=i18n("KDE's PIM suite", "Kontact");
		case eAppKDE:
		default:
			APPEND_CONDUIT("knotes-conduit");
			APPEND_CONDUIT("abbrowser_conduit");
			// Set to the stdaddressbook, reset others to defaults
			addressConfig->setAddressbookType( KPilotWizard_addressConfig::eAbookResource );
			addressConfig->setArchiveDeleted( true );
			addressConfig->setConflictResolution( -1 );
			// nothing to do for knotes conduit yet
			// notesConfig->set...
			// the vcalconduits use the same config file, so set the correct groups
			int version = calendarConfig->conduitVersion();
			calendarConfig->setDefaults();
			calendarConfig->setCalendarType( KPilotWizard_vcalConfig::eCalendarResource );
			calendarConfig->setConduitVersion( version );
			version = todoConfig->conduitVersion();
			todoConfig->setDefaults();
			todoConfig->setCalendarType( KPilotWizard_vcalConfig::eCalendarResource );
			todoConfig->setConduitVersion( version );
			break;
	}
	addressConfig->writeConfig();
	notesConfig->writeConfig();
	todoConfig->writeConfig();
	calendarConfig->writeConfig();

	KPILOT_DELETE(addressConfig);
	KPILOT_DELETE(notesConfig);
	KPILOT_DELETE(todoConfig);
	KPILOT_DELETE(calendarConfig);

	KPilotSettings::setInstalledConduits( conduits );
#undef APPEND_CONDUIT

	QString finishMessage = i18n("KPilot is now configured to sync with %1.").arg(applicationName);
	if (fMode == InDialog)
	{
		finishMessage.append(CSL1("\n"));
		finishMessage.append(i18n(
			"The remaining options in the config dialog are advanced options and can "
			"be used to fine-tune KPilot."));
	}

	KMessageBox::information(this, finishMessage,
		i18n("Automatic Configuration Finished"));
	KPilotSettings::self()->writeConfig();
	QDialog::accept();
}

void ConfigWizard::probeHandheld()
{
	ProbeDialog *probeDialog = new ProbeDialog( this );
	if ( probeDialog->exec() && probeDialog->detected() ) {
		page2->fUserName->setText( probeDialog->userName() );
		page2->fDeviceName->setText( probeDialog->device() );
	}
	KPILOT_DELETE(probeDialog);
}

<|endoftext|>


<commit_before>/***************************************************
  This is a library for our Adafruit 16-channel PWM & Servo driver

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815

  These displays use I2C to communicate, 2 pins are required to
  interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution

  Adapted for Spark Core by Paul Kourany, Sept. 15, 2014
 ****************************************************/
#if defined (SPARK)
 #define WIRE Wire
 #include <math.h>
 #include "Adafruit_PWMServoDriver.h"
#else
#include <Adafruit_PWMServoDriver.h>
#include <Wire.h>
#if defined(__AVR__)
 #define WIRE Wire
#elif defined(CORE_TEENSY) // Teensy boards
 #define WIRE Wire
#else // Arduino Due
 #define WIRE Wire1
#endif
#endif //Spark

#if defined (SPARKLE)
int floor(float val) {
  int i = int(val);
  if (i > val) i--;
    return i;
}
#endif

// Set to true to print some debug messages, or false to disable them.
#define ENABLE_DEBUG_OUTPUT true

Adafruit_PWMServoDriver::Adafruit_PWMServoDriver(uint8_t addr) {
  _i2caddr = addr;
}

void Adafruit_PWMServoDriver::begin(void) {
 WIRE.begin();
 reset();
}

void Adafruit_PWMServoDriver::reset(void) {
 write8(PCA9685_MODE1, 0x0);
}

void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
  //Serial.print("Attempting to set freq ");
  //Serial.println(freq);
  freq *= 0.9;  // Correct for overshoot in the frequency setting (see issue #11).
  float prescaleval = 25000000;
  prescaleval /= 4096;
  prescaleval /= freq;
  prescaleval -= 1;
  if (ENABLE_DEBUG_OUTPUT) {
    Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
  }
  uint8_t prescale = floor(prescaleval + 0.5);
  if (ENABLE_DEBUG_OUTPUT) {
    Serial.print("Final pre-scale: "); Serial.println(prescale);
  }

  uint8_t oldmode = read8(PCA9685_MODE1);
  uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
  write8(PCA9685_MODE1, newmode); // go to sleep
  write8(PCA9685_PRESCALE, prescale); // set the prescaler
  write8(PCA9685_MODE1, oldmode);
  delay(5);
  write8(PCA9685_MODE1, oldmode | 0xa1);  //  This sets the MODE1 register to turn on auto increment.
                                          // This is why the beginTransmission below was not working.
  //  Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
}

void Adafruit_PWMServoDriver::setPWM(uint8_t num, uint16_t on, uint16_t off) {
  //Serial.print("Setting PWM "); Serial.print(num); Serial.print(": "); Serial.print(on); Serial.print("->"); Serial.println(off);

  WIRE.beginTransmission(_i2caddr);
  WIRE.write(LED0_ON_L+4*num);
  WIRE.write(on);
  WIRE.write(on>>8);
  WIRE.write(off);
  WIRE.write(off>>8);
  WIRE.endTransmission();
}

// Sets pin without having to deal with on/off tick placement and properly handles
// a zero value as completely off.  Optional invert parameter supports inverting
// the pulse for sinking to ground.  Val should be a value from 0 to 4095 inclusive.
void Adafruit_PWMServoDriver::setPin(uint8_t num, uint16_t val, bool invert)
{
  // Clamp value between 0 and 4095 inclusive.
  val = min(val, 4095);
  if (invert) {
    if (val == 0) {
      // Special value for signal fully on.
      setPWM(num, 4096, 0);
    }
    else if (val == 4095) {
      // Special value for signal fully off.
      setPWM(num, 0, 4096);
    }
    else {
      setPWM(num, 0, 4095-val);
    }
  }
  else {
    if (val == 4095) {
      // Special value for signal fully on.
      setPWM(num, 4096, 0);
    }
    else if (val == 0) {
      // Special value for signal fully off.
      setPWM(num, 0, 4096);
    }
    else {
      setPWM(num, 0, val);
    }
  }
}

uint8_t Adafruit_PWMServoDriver::read8(uint8_t addr) {
  WIRE.beginTransmission(_i2caddr);
  WIRE.write(addr);
  WIRE.endTransmission();

  WIRE.requestFrom((uint8_t)_i2caddr, (uint8_t)1);
  return WIRE.read();
}

void Adafruit_PWMServoDriver::write8(uint8_t addr, uint8_t d) {
  WIRE.beginTransmission(_i2caddr);
  WIRE.write(addr);
  WIRE.write(d);
  WIRE.endTransmission();
}
<commit_msg>Update Adafruit_PWMServoDriver.cpp<commit_after>/***************************************************
  This is a library for our Adafruit 16-channel PWM & Servo driver

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815

  These displays use I2C to communicate, 2 pins are required to
  interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution

  Adapted for Spark Core by Paul Kourany, Sept. 15, 2014
 ****************************************************/
#if defined (SPARK)
 #define WIRE Wire
 #include <math.h>
 #include "Adafruit_PWMServoDriver.h"
#else
#include <Adafruit_PWMServoDriver.h>
#include <Wire.h>
#if defined(__AVR__)
 #define WIRE Wire
#elif defined(CORE_TEENSY) // Teensy boards
 #define WIRE Wire
#else // Arduino Due
 #define WIRE Wire1
#endif
#endif //Spark

// Set to true to print some debug messages, or false to disable them.
#define ENABLE_DEBUG_OUTPUT true

Adafruit_PWMServoDriver::Adafruit_PWMServoDriver(uint8_t addr) {
  _i2caddr = addr;
}

void Adafruit_PWMServoDriver::begin(void) {
 WIRE.begin();
 reset();
}

void Adafruit_PWMServoDriver::reset(void) {
 write8(PCA9685_MODE1, 0x0);
}

void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
  //Serial.print("Attempting to set freq ");
  //Serial.println(freq);
  freq *= 0.9;  // Correct for overshoot in the frequency setting (see issue #11).
  float prescaleval = 25000000;
  prescaleval /= 4096;
  prescaleval /= freq;
  prescaleval -= 1;
  if (ENABLE_DEBUG_OUTPUT) {
    Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
  }
  uint8_t prescale = floor(prescaleval + 0.5);
  if (ENABLE_DEBUG_OUTPUT) {
    Serial.print("Final pre-scale: "); Serial.println(prescale);
  }

  uint8_t oldmode = read8(PCA9685_MODE1);
  uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
  write8(PCA9685_MODE1, newmode); // go to sleep
  write8(PCA9685_PRESCALE, prescale); // set the prescaler
  write8(PCA9685_MODE1, oldmode);
  delay(5);
  write8(PCA9685_MODE1, oldmode | 0xa1);  //  This sets the MODE1 register to turn on auto increment.
                                          // This is why the beginTransmission below was not working.
  //  Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
}

void Adafruit_PWMServoDriver::setPWM(uint8_t num, uint16_t on, uint16_t off) {
  //Serial.print("Setting PWM "); Serial.print(num); Serial.print(": "); Serial.print(on); Serial.print("->"); Serial.println(off);

  WIRE.beginTransmission(_i2caddr);
  WIRE.write(LED0_ON_L+4*num);
  WIRE.write(on);
  WIRE.write(on>>8);
  WIRE.write(off);
  WIRE.write(off>>8);
  WIRE.endTransmission();
}

// Sets pin without having to deal with on/off tick placement and properly handles
// a zero value as completely off.  Optional invert parameter supports inverting
// the pulse for sinking to ground.  Val should be a value from 0 to 4095 inclusive.
void Adafruit_PWMServoDriver::setPin(uint8_t num, uint16_t val, bool invert)
{
  // Clamp value between 0 and 4095 inclusive.
  val = min(val, 4095);
  if (invert) {
    if (val == 0) {
      // Special value for signal fully on.
      setPWM(num, 4096, 0);
    }
    else if (val == 4095) {
      // Special value for signal fully off.
      setPWM(num, 0, 4096);
    }
    else {
      setPWM(num, 0, 4095-val);
    }
  }
  else {
    if (val == 4095) {
      // Special value for signal fully on.
      setPWM(num, 4096, 0);
    }
    else if (val == 0) {
      // Special value for signal fully off.
      setPWM(num, 0, 4096);
    }
    else {
      setPWM(num, 0, val);
    }
  }
}

uint8_t Adafruit_PWMServoDriver::read8(uint8_t addr) {
  WIRE.beginTransmission(_i2caddr);
  WIRE.write(addr);
  WIRE.endTransmission();

  WIRE.requestFrom((uint8_t)_i2caddr, (uint8_t)1);
  return WIRE.read();
}

void Adafruit_PWMServoDriver::write8(uint8_t addr, uint8_t d) {
  WIRE.beginTransmission(_i2caddr);
  WIRE.write(addr);
  WIRE.write(d);
  WIRE.endTransmission();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: transliterationImpl.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 16:57:28 $
 *
 *  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 _I18N_TRANSLITERATIONIMPL_HXX_
#define _I18N_TRANSLITERATIONIMPL_HXX_

#include <com/sun/star/i18n/XLocaleData.hpp>
#include <com/sun/star/i18n/XExtendedTransliteration.hpp>
#include <cppuhelper/implbase2.hxx> // helper for implementations
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <sal/types.h>

namespace com { namespace sun { namespace star { namespace i18n {

#if OSL_DEBUG_LEVEL > 1
#define RETURN_DEBUG_STRING (rtl::OUString::createFromAscii("return from transliterationImpl"));
#define RETURN_DEBUG_NUMBER 'TRAN'
#else
#define RETURN_DEBUG_STRING
#define RETURN_DEBUG_NUMBER
#endif

class TransliterationImpl : public cppu::WeakImplHelper2
<
    com::sun::star::i18n::XExtendedTransliteration,
    com::sun::star::lang::XServiceInfo
>
{
public:
    // Constructors
    TransliterationImpl(const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory >& xMSF);
    // Destructor
    ~TransliterationImpl();

    // Methods
    virtual rtl::OUString SAL_CALL getName(  ) throw(com::sun::star::uno::RuntimeException) ;
    virtual sal_Int16 SAL_CALL getType(  ) throw(com::sun::star::uno::RuntimeException) ;

    virtual void SAL_CALL loadModule( TransliterationModules modName, const com::sun::star::lang::Locale& rLocale )
        throw(com::sun::star::uno::RuntimeException) ;
    virtual void SAL_CALL loadModuleNew( const com::sun::star::uno::Sequence< TransliterationModulesNew >& modName,
        const com::sun::star::lang::Locale& rLocale ) throw(com::sun::star::uno::RuntimeException) ;
    virtual void SAL_CALL loadModuleByImplName( const rtl::OUString& implName,
        const com::sun::star::lang::Locale& rLocale ) throw(com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL loadModulesByImplNames(const com::sun::star::uno::Sequence< rtl::OUString >& modNamelist,
        const com::sun::star::lang::Locale& rLocale) throw(com::sun::star::uno::RuntimeException);

    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getAvailableModules(
        const com::sun::star::lang::Locale& rLocale, sal_Int16 sType )
        throw(com::sun::star::uno::RuntimeException);

    virtual rtl::OUString SAL_CALL transliterate( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
        com::sun::star::uno::Sequence< sal_Int32 >& offset  ) throw(com::sun::star::uno::RuntimeException) ;

    virtual rtl::OUString SAL_CALL folding( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
        com::sun::star::uno::Sequence< sal_Int32 >& offset ) throw(com::sun::star::uno::RuntimeException);

    // Methods in XExtendedTransliteration
    virtual rtl::OUString SAL_CALL transliterateString2String( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount )
        throw(com::sun::star::uno::RuntimeException) ;
    virtual rtl::OUString SAL_CALL transliterateChar2String( sal_Unicode inChar )
        throw(com::sun::star::uno::RuntimeException) ;
    virtual sal_Unicode SAL_CALL transliterateChar2Char( sal_Unicode inChar )
        throw(com::sun::star::i18n::MultipleCharsOutputException,
                com::sun::star::uno::RuntimeException) ;

/*
    virtual void SAL_CALL createCascadeInstance( const com::sun::star::uno::Sequence< rtl::OUString >& modNamelist,
        const com::sun::star::lang::Locale& rLocale ) throw(com::sun::star::uno::RuntimeException) ;
    virtual rtl::OUString SAL_CALL folding_reverse( const rtl::OUString& inStr, sal_Int32 startPos,
        sal_Int32 nCount ) throw(com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL transliterateMatch( const rtl::OUString& content, sal_Int32 pos1, sal_Int32 nCount1,
        const rtl::OUString& pattern, sal_Int32 pos2, sal_Int32 nCount2 )
        throw(com::sun::star::uno::RuntimeException);
*/
    virtual sal_Bool SAL_CALL equals( const rtl::OUString& str1, sal_Int32 pos1, sal_Int32 nCount1,
        sal_Int32& nMatch1, const rtl::OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2 )
        throw(com::sun::star::uno::RuntimeException);
    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL transliterateRange( const rtl::OUString& str1,
        const rtl::OUString& str2 ) throw(com::sun::star::uno::RuntimeException) ;

    virtual sal_Int32 SAL_CALL compareSubstring( const rtl::OUString& s1, sal_Int32 off1, sal_Int32 len1,
        const rtl::OUString& s2, sal_Int32 off2, sal_Int32 len2) throw(com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL compareString( const rtl::OUString& s1, const rtl::OUString& s2)
        throw(com::sun::star::uno::RuntimeException);

    //XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName(void) throw( com::sun::star::uno::RuntimeException );
    virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& ServiceName)
        throw( com::sun::star::uno::RuntimeException );
    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void)
        throw( com::sun::star::uno::RuntimeException );

private:
#define maxCascade 27
    com::sun::star::uno::Reference< com::sun::star::i18n::XExtendedTransliteration > bodyCascade[maxCascade];
    sal_Int16 numCascade;
    sal_Bool caseignoreOnly;
    com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xSMgr;
    com::sun::star::uno::Reference< XLocaleData > localedata;
    com::sun::star::uno::Reference< com::sun::star::i18n::XExtendedTransliteration > caseignore;

    virtual sal_Bool SAL_CALL loadModuleByName( const rtl::OUString& implName,
        com::sun::star::uno::Reference<com::sun::star::i18n::XExtendedTransliteration> & body, const com::sun::star::lang::Locale& rLocale)
        throw(com::sun::star::uno::RuntimeException);

    void clear();

    com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getRange(
        const com::sun::star::uno::Sequence< rtl::OUString > &inStrs,
        sal_Int32 length, const sal_Int16 _nCascade)
        throw(com::sun::star::uno::RuntimeException);
};

} } } }

#endif
<commit_msg>INTEGRATION: CWS kohei01 (1.6.196); FILE MERGED 2007/12/16 21:34:26 kohei 1.6.196.1: Issue number: i80981 Submitted by: kohei Reviewed by: kohei<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: transliterationImpl.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2008-01-29 08:04:26 $
 *
 *  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 _I18N_TRANSLITERATIONIMPL_HXX_
#define _I18N_TRANSLITERATIONIMPL_HXX_

#include <com/sun/star/i18n/XLocaleData.hpp>
#include <com/sun/star/i18n/XExtendedTransliteration.hpp>
#include <cppuhelper/implbase2.hxx> // helper for implementations
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <sal/types.h>

namespace com { namespace sun { namespace star { namespace i18n {

#if OSL_DEBUG_LEVEL > 1
#define RETURN_DEBUG_STRING (rtl::OUString::createFromAscii("return from transliterationImpl"));
#define RETURN_DEBUG_NUMBER 'TRAN'
#else
#define RETURN_DEBUG_STRING
#define RETURN_DEBUG_NUMBER
#endif

class TransliterationImpl : public cppu::WeakImplHelper2
<
    com::sun::star::i18n::XExtendedTransliteration,
    com::sun::star::lang::XServiceInfo
>
{
public:
    // Constructors
    TransliterationImpl(const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory >& xMSF);
    // Destructor
    ~TransliterationImpl();

    // Methods
    virtual rtl::OUString SAL_CALL getName(  ) throw(com::sun::star::uno::RuntimeException) ;
    virtual sal_Int16 SAL_CALL getType(  ) throw(com::sun::star::uno::RuntimeException) ;

    virtual void SAL_CALL loadModule( TransliterationModules modName, const com::sun::star::lang::Locale& rLocale )
        throw(com::sun::star::uno::RuntimeException) ;
    virtual void SAL_CALL loadModuleNew( const com::sun::star::uno::Sequence< TransliterationModulesNew >& modName,
        const com::sun::star::lang::Locale& rLocale ) throw(com::sun::star::uno::RuntimeException) ;
    virtual void SAL_CALL loadModuleByImplName( const rtl::OUString& implName,
        const com::sun::star::lang::Locale& rLocale ) throw(com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL loadModulesByImplNames(const com::sun::star::uno::Sequence< rtl::OUString >& modNamelist,
        const com::sun::star::lang::Locale& rLocale) throw(com::sun::star::uno::RuntimeException);

    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getAvailableModules(
        const com::sun::star::lang::Locale& rLocale, sal_Int16 sType )
        throw(com::sun::star::uno::RuntimeException);

    virtual rtl::OUString SAL_CALL transliterate( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
        com::sun::star::uno::Sequence< sal_Int32 >& offset  ) throw(com::sun::star::uno::RuntimeException) ;

    virtual rtl::OUString SAL_CALL folding( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
        com::sun::star::uno::Sequence< sal_Int32 >& offset ) throw(com::sun::star::uno::RuntimeException);

    // Methods in XExtendedTransliteration
    virtual rtl::OUString SAL_CALL transliterateString2String( const rtl::OUString& inStr, sal_Int32 startPos, sal_Int32 nCount )
        throw(com::sun::star::uno::RuntimeException) ;
    virtual rtl::OUString SAL_CALL transliterateChar2String( sal_Unicode inChar )
        throw(com::sun::star::uno::RuntimeException) ;
    virtual sal_Unicode SAL_CALL transliterateChar2Char( sal_Unicode inChar )
        throw(com::sun::star::i18n::MultipleCharsOutputException,
                com::sun::star::uno::RuntimeException) ;

/*
    virtual void SAL_CALL createCascadeInstance( const com::sun::star::uno::Sequence< rtl::OUString >& modNamelist,
        const com::sun::star::lang::Locale& rLocale ) throw(com::sun::star::uno::RuntimeException) ;
    virtual rtl::OUString SAL_CALL folding_reverse( const rtl::OUString& inStr, sal_Int32 startPos,
        sal_Int32 nCount ) throw(com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL transliterateMatch( const rtl::OUString& content, sal_Int32 pos1, sal_Int32 nCount1,
        const rtl::OUString& pattern, sal_Int32 pos2, sal_Int32 nCount2 )
        throw(com::sun::star::uno::RuntimeException);
*/
    virtual sal_Bool SAL_CALL equals( const rtl::OUString& str1, sal_Int32 pos1, sal_Int32 nCount1,
        sal_Int32& nMatch1, const rtl::OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2 )
        throw(com::sun::star::uno::RuntimeException);
    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL transliterateRange( const rtl::OUString& str1,
        const rtl::OUString& str2 ) throw(com::sun::star::uno::RuntimeException) ;

    virtual sal_Int32 SAL_CALL compareSubstring( const rtl::OUString& s1, sal_Int32 off1, sal_Int32 len1,
        const rtl::OUString& s2, sal_Int32 off2, sal_Int32 len2) throw(com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL compareString( const rtl::OUString& s1, const rtl::OUString& s2)
        throw(com::sun::star::uno::RuntimeException);

    //XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName(void) throw( com::sun::star::uno::RuntimeException );
    virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& ServiceName)
        throw( com::sun::star::uno::RuntimeException );
    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void)
        throw( com::sun::star::uno::RuntimeException );

private:
#define maxCascade 27
    com::sun::star::uno::Reference< com::sun::star::i18n::XExtendedTransliteration > bodyCascade[maxCascade];
    sal_Int16 numCascade;
    sal_Bool caseignoreOnly;
    com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xSMgr;
    com::sun::star::uno::Reference< XLocaleData > localedata;
    com::sun::star::uno::Reference< com::sun::star::i18n::XExtendedTransliteration > caseignore;

    /** structure to cache the last transliteration body used. */
    struct TransBody
    {
        ::osl::Mutex mutex;
        ::rtl::OUString Name;
        ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XExtendedTransliteration > Body;
    };
    static TransBody lastTransBody;

    virtual sal_Bool SAL_CALL loadModuleByName( const rtl::OUString& implName,
        com::sun::star::uno::Reference<com::sun::star::i18n::XExtendedTransliteration> & body, const com::sun::star::lang::Locale& rLocale)
        throw(com::sun::star::uno::RuntimeException);

    void clear();

    void loadBody( ::rtl::OUString &implName,
        ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XExtendedTransliteration >& body )
        throw (::com::sun::star::uno::RuntimeException);

    com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getRange(
        const com::sun::star::uno::Sequence< rtl::OUString > &inStrs,
        sal_Int32 length, const sal_Int16 _nCascade)
        throw(com::sun::star::uno::RuntimeException);
};

} } } }

#endif
<|endoftext|>


<commit_before>#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

#include "variant.hpp"
#include <cstdint>
#include <limits>
#include <string>
#include <ostream>
#include <memory>

using namespace mapbox;

TEST_CASE( "variant version", "[variant]" ) {
    unsigned int version = VARIANT_VERSION;
    REQUIRE(version == 100);
    #if VARIANT_VERSION == 100
        REQUIRE(true);
    #else
        REQUIRE(false);
    #endif
}

TEST_CASE( "variant can be moved into vector", "[variant]" ) {
    typedef util::variant<bool,std::string> variant_type;
    variant_type v(std::string("test"));
    std::vector<variant_type> vec;
    vec.emplace_back(std::move(v));
    REQUIRE(v.get<std::string>() != std::string("test"));
    REQUIRE(vec.at(0).get<std::string>() == std::string("test"));
}

TEST_CASE( "variant should support built-in types", "[variant]" ) {
    SECTION( "bool" ) {
        util::variant<bool> v(true);
        REQUIRE(v.valid());
        REQUIRE(v.is<bool>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<bool>() == true);
        v.set<bool>(false);
        REQUIRE(v.get<bool>() == false);
        v = true;
        REQUIRE(v == util::variant<bool>(true));
    }
    SECTION( "nullptr" ) {
        typedef std::nullptr_t value_type;
        util::variant<value_type> v(nullptr);
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        // TODO: commented since it breaks on windows: 'operator << is ambiguous'
        //REQUIRE(v.get<value_type>() == nullptr);
        // FIXME: does not compile: ./variant.hpp:340:14: error: use of overloaded operator '<<' is ambiguous (with operand types 'std::__1::basic_ostream<char>' and 'const nullptr_t')
        // https://github.com/mapbox/variant/issues/14
        //REQUIRE(v == util::variant<value_type>(nullptr));
    }
    SECTION( "unique_ptr" ) {
        typedef std::unique_ptr<std::string> value_type;
        util::variant<value_type> v(value_type(new std::string("hello")));
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(*v.get<value_type>().get() == *value_type(new std::string("hello")).get());
    }
    SECTION( "string" ) {
        typedef std::string value_type;
        util::variant<value_type> v(value_type("hello"));
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == value_type("hello"));
        v.set<value_type>(value_type("there"));
        REQUIRE(v.get<value_type>() == value_type("there"));
        v = value_type("variant");
        REQUIRE(v == util::variant<value_type>(value_type("variant")));
    }
    SECTION( "size_t" ) {
        typedef std::size_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(value_type(0));
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int8_t" ) {
        typedef std::int8_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int16_t" ) {
        typedef std::int16_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int32_t" ) {
        typedef std::int32_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int64_t" ) {
        typedef std::int64_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
}

struct MissionInteger
{
    typedef uint64_t value_type;
    value_type val_;
    public:
      MissionInteger(uint64_t val) :
       val_(val) {}

    bool operator==(MissionInteger const& rhs) const
    {
        return (val_ == rhs.get());
    }

    uint64_t get() const
    {
        return val_;
    }
};

// TODO - remove after https://github.com/mapbox/variant/issues/14
std::ostream& operator<< (std::ostream& os, MissionInteger const& rhs)
{
    os << rhs.get();
    return os;
}

TEST_CASE( "variant should support custom types", "[variant]" ) {
    // http://www.missionintegers.com/integer/34838300
    util::variant<MissionInteger> v(MissionInteger(34838300));
    REQUIRE(v.valid());
    REQUIRE(v.is<MissionInteger>());
    REQUIRE(v.get_type_index() == 0);
    REQUIRE(v.get<MissionInteger>() == MissionInteger(34838300));
    REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(34838300));
    // TODO: should both of the set usages below compile?
    v.set<MissionInteger>(MissionInteger::value_type(0));
    v.set<MissionInteger>(MissionInteger(0));
    REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(0));
    v = MissionInteger(1);
    REQUIRE(v == util::variant<MissionInteger>(MissionInteger(1)));
}

// Test internal api
TEST_CASE( "variant should correctly index types", "[variant]" ) {
    typedef util::variant<bool,std::string,std::uint64_t,std::int64_t,double,float> variant_type;
    // Index is in reverse order
    REQUIRE(variant_type(true).get_type_index() == 5);
    REQUIRE(variant_type(std::string("test")).get_type_index() == 4);
    REQUIRE(variant_type(std::uint64_t(0)).get_type_index() == 3);
    REQUIRE(variant_type(std::int64_t(0)).get_type_index() == 2);
    REQUIRE(variant_type(double(0.0)).get_type_index() == 1);
    REQUIRE(variant_type(float(0.0)).get_type_index() == 0);
}

TEST_CASE( "variant type traits", "[variant::detail]" ) {
    // Users should not create variants with duplicated types
    // however our type indexing should still work
    // Index is in reverse order
    REQUIRE((util::detail::type_traits<bool, bool, int, double, std::string>::id == 3));
    REQUIRE((util::detail::type_traits<int, bool, int, double, std::string>::id == 2));
    REQUIRE((util::detail::type_traits<double, bool, int, double, std::string>::id == 1));
    REQUIRE((util::detail::type_traits<std::string, bool, int, double, std::string>::id == 0));
    REQUIRE((util::detail::type_traits<long, bool, int, double, std::string>::id == util::detail::invalid_value));
    REQUIRE((util::detail::type_traits<std::vector<int>, bool, int, double, std::string>::id == util::detail::invalid_value));
}

int main (int argc, char* const argv[])
{
    int result = Catch::Session().run( argc, argv );
    if (!result) printf("\x1b[1;32m ✓ \x1b[0m\n");
    return result;
}
<commit_msg>add default ctor test<commit_after>#define CATCH_CONFIG_RUNNER
#include "catch.hpp"

#include "variant.hpp"
#include <cstdint>
#include <limits>
#include <string>
#include <ostream>
#include <memory>

using namespace mapbox;

TEST_CASE( "variant version", "[variant]" ) {
    unsigned int version = VARIANT_VERSION;
    REQUIRE(version == 100);
    #if VARIANT_VERSION == 100
        REQUIRE(true);
    #else
        REQUIRE(false);
    #endif
}

TEST_CASE( "variant can be moved into vector", "[variant]" ) {
    typedef util::variant<bool,std::string> variant_type;
    variant_type v(std::string("test"));
    std::vector<variant_type> vec;
    vec.emplace_back(std::move(v));
    REQUIRE(v.get<std::string>() != std::string("test"));
    REQUIRE(vec.at(0).get<std::string>() == std::string("test"));
}

TEST_CASE( "variant should support built-in types", "[variant]" ) {
    SECTION( "bool" ) {
        util::variant<bool> v(true);
        REQUIRE(v.valid());
        REQUIRE(v.is<bool>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<bool>() == true);
        v.set<bool>(false);
        REQUIRE(v.get<bool>() == false);
        v = true;
        REQUIRE(v == util::variant<bool>(true));
    }
    SECTION( "nullptr" ) {
        typedef std::nullptr_t value_type;
        util::variant<value_type> v(nullptr);
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        // TODO: commented since it breaks on windows: 'operator << is ambiguous'
        //REQUIRE(v.get<value_type>() == nullptr);
        // FIXME: does not compile: ./variant.hpp:340:14: error: use of overloaded operator '<<' is ambiguous (with operand types 'std::__1::basic_ostream<char>' and 'const nullptr_t')
        // https://github.com/mapbox/variant/issues/14
        //REQUIRE(v == util::variant<value_type>(nullptr));
    }
    SECTION( "unique_ptr" ) {
        typedef std::unique_ptr<std::string> value_type;
        util::variant<value_type> v(value_type(new std::string("hello")));
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(*v.get<value_type>().get() == *value_type(new std::string("hello")).get());
    }
    SECTION( "string" ) {
        typedef std::string value_type;
        util::variant<value_type> v(value_type("hello"));
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == value_type("hello"));
        v.set<value_type>(value_type("there"));
        REQUIRE(v.get<value_type>() == value_type("there"));
        v = value_type("variant");
        REQUIRE(v == util::variant<value_type>(value_type("variant")));
    }
    SECTION( "size_t" ) {
        typedef std::size_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(value_type(0));
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int8_t" ) {
        typedef std::int8_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int16_t" ) {
        typedef std::int16_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int32_t" ) {
        typedef std::int32_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
    SECTION( "int64_t" ) {
        typedef std::int64_t value_type;
        util::variant<value_type> v(std::numeric_limits<value_type>::max());
        REQUIRE(v.valid());
        REQUIRE(v.is<value_type>());
        REQUIRE(v.get_type_index() == 0);
        REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
        v.set<value_type>(0);
        REQUIRE(v.get<value_type>() == value_type(0));
        v = value_type(1);
        REQUIRE(v == util::variant<value_type>(value_type(1)));
    }
}

struct MissionInteger
{
    typedef uint64_t value_type;
    value_type val_;
    public:
      MissionInteger(uint64_t val) :
       val_(val) {}

    bool operator==(MissionInteger const& rhs) const
    {
        return (val_ == rhs.get());
    }

    uint64_t get() const
    {
        return val_;
    }
};

// TODO - remove after https://github.com/mapbox/variant/issues/14
std::ostream& operator<< (std::ostream& os, MissionInteger const& rhs)
{
    os << rhs.get();
    return os;
}

TEST_CASE( "variant should support custom types", "[variant]" ) {
    // http://www.missionintegers.com/integer/34838300
    util::variant<MissionInteger> v(MissionInteger(34838300));
    REQUIRE(v.valid());
    REQUIRE(v.is<MissionInteger>());
    REQUIRE(v.get_type_index() == 0);
    REQUIRE(v.get<MissionInteger>() == MissionInteger(34838300));
    REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(34838300));
    // TODO: should both of the set usages below compile?
    v.set<MissionInteger>(MissionInteger::value_type(0));
    v.set<MissionInteger>(MissionInteger(0));
    REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(0));
    v = MissionInteger(1);
    REQUIRE(v == util::variant<MissionInteger>(MissionInteger(1)));
}

// Test internal api
TEST_CASE( "variant should correctly index types", "[variant]" ) {
    typedef util::variant<bool,std::string,std::uint64_t,std::int64_t,double,float> variant_type;
    // Index is in reverse order
    REQUIRE(variant_type(true).get_type_index() == 5);
    REQUIRE(variant_type(std::string("test")).get_type_index() == 4);
    REQUIRE(variant_type(std::uint64_t(0)).get_type_index() == 3);
    REQUIRE(variant_type(std::int64_t(0)).get_type_index() == 2);
    REQUIRE(variant_type(double(0.0)).get_type_index() == 1);
    REQUIRE(variant_type(float(0.0)).get_type_index() == 0);
}

TEST_CASE( "variant type traits", "[variant::detail]" ) {
    // Users should not create variants with duplicated types
    // however our type indexing should still work
    // Index is in reverse order
    REQUIRE((util::detail::type_traits<bool, bool, int, double, std::string>::id == 3));
    REQUIRE((util::detail::type_traits<int, bool, int, double, std::string>::id == 2));
    REQUIRE((util::detail::type_traits<double, bool, int, double, std::string>::id == 1));
    REQUIRE((util::detail::type_traits<std::string, bool, int, double, std::string>::id == 0));
    REQUIRE((util::detail::type_traits<long, bool, int, double, std::string>::id == util::detail::invalid_value));
    REQUIRE((util::detail::type_traits<std::vector<int>, bool, int, double, std::string>::id == util::detail::invalid_value));
}

TEST_CASE( "variant default constructor", "variant()" ) {
    // By default variant is initilised with (default constructed) first type in template parameters pack
    // As a reusult first type in Types... must be defaul constructable
    REQUIRE((util::variant<int, double, std::string>().get_type_index() == 0));
}

int main (int argc, char* const argv[])
{
    int result = Catch::Session().run( argc, argv );
    if (!result) printf("\x1b[1;32m ✓ \x1b[0m\n");
    return result;
}
<|endoftext|>


<commit_before>#include "VTRenderer.h"
#include "imgui_impl_glfw_gl3.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <atomic>
#include <condition_variable>
#include <fstream>
#include <lamure/vt/VTConfig.h>
#include <lamure/vt/ren/CutDatabase.h>
#include <lamure/vt/ren/CutUpdate.h>
#include <queue>
#include <unordered_map>

char *get_cmd_option(char **begin, char **end, const std::string &option)
{
    char **it = std::find(begin, end, option);
    if(it != end && ++it != end)
        return *it;
    return nullptr;
}

bool cmd_option_exists(char **begin, char **end, const std::string &option) { return std::find(begin, end, option) != end; }

struct Window
{
    Window()
    {
        _mouse_button_state = MouseButtonState::IDLE;
        _trackball_manipulator.dolly(2.5f);
    }

    unsigned int _width;
    unsigned int _height;

    GLFWwindow *_glfw_window;

    scm::gl::trackball_manipulator _trackball_manipulator;

    float _ref_rot_x;
    float _ref_rot_y;

    float _scale = 0.16f;

    enum MouseButtonState
    {
        LEFT = 0,
        WHEEL = 1,
        RIGHT = 2,
        IDLE = 3
    };

    MouseButtonState _mouse_button_state;
};

std::list<Window *> _windows;
Window *_current_context = nullptr;
vt::CutUpdate *_cut_update = nullptr;

class EventHandler
{
  private:
    static float calculate_factor(float scale)
    {
        return -1.0f/109.0f * scale * scale + 1081.0f/10900.0f * scale + 0.01f;
    }

  public:
    static void on_error(int _err_code, const char *err_msg) { throw std::runtime_error(err_msg); }
    static void on_window_resize(GLFWwindow *glfw_window, int width, int height)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
        window->_height = (uint32_t)height;
        window->_width = (uint32_t)width;
    }
    static void on_window_key_press(GLFWwindow *glfw_window, int key, int scancode, int action, int mods)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
        switch(key)
        {
            case GLFW_KEY_ESCAPE:
                std::cout << "should close" << std::endl;
                glfwSetWindowShouldClose(glfw_window, GL_TRUE);
                break;
            case GLFW_KEY_P:
                if (action == GLFW_PRESS) {
                    _cut_update->set_freeze_dispatch(!_cut_update->get_freeze_dispatch());
                }
                break;
            case GLFW_KEY_RIGHT:
                if (action != GLFW_RELEASE) {
                    window->_trackball_manipulator.translation(-calculate_factor(window->_scale), 0.0f);
                }
                break;
            case GLFW_KEY_LEFT:
                if (action != GLFW_RELEASE) {
                    window->_trackball_manipulator.translation(calculate_factor(window->_scale), 0.0f);
                }
                break;
            case GLFW_KEY_UP:
                if (action != GLFW_RELEASE) {
                    window->_trackball_manipulator.translation(0.0f, -calculate_factor(window->_scale));
                }
                break;
            case GLFW_KEY_DOWN:
                if (action != GLFW_RELEASE) {
                    window->_trackball_manipulator.translation(0.0f, calculate_factor(window->_scale));
                }
                break;
        }

#ifndef NDEBUG
        ImGui_ImplGlfwGL3_KeyCallback(glfw_window, key, scancode, action, mods);
#endif
    }
    static void on_window_char(GLFWwindow *glfw_window, unsigned int codepoint)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
#ifndef NDEBUG
        ImGui_ImplGlfwGL3_CharCallback(glfw_window, codepoint);
#endif
    }
    static void on_window_button_press(GLFWwindow *glfw_window, int button, int action, int mods)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
        if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
        {
            window->_mouse_button_state = Window::MouseButtonState::LEFT;
        }
        else if(button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS)
        {
            window->_mouse_button_state = Window::MouseButtonState::WHEEL;
        }
        else if(button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
        {
            window->_mouse_button_state = Window::MouseButtonState::RIGHT;
        }
        else
        {
            window->_mouse_button_state = Window::MouseButtonState::IDLE;
        }

#ifndef NDEBUG
        ImGui_ImplGlfwGL3_MouseButtonCallback(glfw_window, button, action, mods);
#endif
    }
    static void on_window_move_cursor(GLFWwindow *glfw_window, double xpos, double ypos)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);

        float x = ((float)xpos / window->_width - 0.5f) * 6.28f;
        float y = ((float)ypos / window->_height - 0.5f) * 6.28f;

        switch(window->_mouse_button_state)
        {
        case Window::MouseButtonState::LEFT:
        {
            window->_trackball_manipulator.rotation(window->_ref_rot_x, 0, x, 0);
        }
        break;
        case Window::MouseButtonState::RIGHT:
        {
            window->_trackball_manipulator.rotation(0, window->_ref_rot_y, 0, y);
        }
        break;
        default:
            break;
        }

        window->_ref_rot_x = x;
        window->_ref_rot_y = y;
    }
    static void on_window_scroll(GLFWwindow *glfw_window, double xoffset, double yoffset)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);

        float scale_factor = -1.0f/109.0f * window->_scale * window->_scale + 1081.0f/10900.0f * window->_scale + 0.01f;
        window->_scale = std::max(window->_scale + (float)yoffset * scale_factor, -0.1f);

#ifndef NDEBUG
        ImGui_ImplGlfwGL3_ScrollCallback(glfw_window, xoffset, yoffset);
#endif
    }
    static void on_window_enter(GLFWwindow *glfw_window, int entered)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
        // TODO
    }
};

void make_context_current(Window *_window)
{
    if(_window != nullptr)
    {
        glfwMakeContextCurrent(_window->_glfw_window);
        _current_context = _window;
    }
}

Window *create_window(unsigned int width, unsigned int height, const std::string &title, GLFWmonitor *monitor, Window *share)
{
    Window *previous_context = _current_context;

    Window *new_window = new Window();

    new_window->_glfw_window = nullptr;
    new_window->_width = width;
    new_window->_height = height;

    glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, 1);
    glfwWindowHint(GLFW_FOCUSED, 1);
#ifndef NDEBUG
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
#else
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false);
#endif

    if(share != nullptr)
    {
        new_window->_glfw_window = glfwCreateWindow(width, height, title.c_str(), monitor, share->_glfw_window);
    }
    else
    {
        new_window->_glfw_window = glfwCreateWindow(width, height, title.c_str(), monitor, nullptr);
    }

    if(new_window->_glfw_window == nullptr)
    {
        std::runtime_error("GLFW window creation failed");
    }

    make_context_current(new_window);

    glfwSetKeyCallback         (new_window->_glfw_window, &EventHandler::on_window_key_press);
    glfwSetCharCallback        (new_window->_glfw_window, &EventHandler::on_window_char);
    glfwSetMouseButtonCallback (new_window->_glfw_window, &EventHandler::on_window_button_press);
    glfwSetCursorPosCallback   (new_window->_glfw_window, &EventHandler::on_window_move_cursor);
    glfwSetScrollCallback      (new_window->_glfw_window, &EventHandler::on_window_scroll);
    glfwSetCursorEnterCallback (new_window->_glfw_window, &EventHandler::on_window_enter);

    glfwSetWindowUserPointer(new_window->_glfw_window, new_window);

    _windows.push_back(new_window);

    make_context_current(previous_context);

    return new_window;
}

bool should_close()
{
    if(_windows.empty())
        return true;

    std::list<Window *> to_delete;
    for(const auto &window : _windows)
    {
        if(glfwWindowShouldClose(window->_glfw_window))
        {
            to_delete.push_back(window);
        }
    }

    if(!to_delete.empty())
    {
        for(auto &window : to_delete)
        {
            ImGui_ImplGlfwGL3_Shutdown();

            glfwDestroyWindow(window->_glfw_window);

            delete window;

            _windows.remove(window);
        }
    }

    return _windows.empty();
}

void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *param)
{
    switch(severity)
    {
    case GL_DEBUG_SEVERITY_HIGH:
    {
        fprintf(stderr, "GL_DEBUG_SEVERITY_HIGH: %s type = 0x%x, message = %s\n", (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type, message);
    }
    break;
    case GL_DEBUG_SEVERITY_MEDIUM:
    {
        fprintf(stderr, "GL_DEBUG_SEVERITY_MEDIUM: %s type = 0x%x, message = %s\n", (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type, message);
    }
    break;
    case GL_DEBUG_SEVERITY_LOW:
    {
        fprintf(stderr, "GL_DEBUG_SEVERITY_LOW: %s type = 0x%x, message = %s\n", (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type, message);
    }
    break;
    default:
        // ignore
        break;
    }
}

int main(int argc, char *argv[])
{
    vt::VTConfig::CONFIG_PATH = "configuration_template.ini";
    vt::VTConfig::get_instance().define_size_physical_texture(64, 8192);

    uint32_t data_world_map_id = vt::CutDatabase::get_instance().register_dataset(
            "/mnt/terabytes_of_textures/montblanc/montblanc_w1202116_h304384.atlas");

    uint16_t view_id = vt::CutDatabase::get_instance().register_view();
    uint16_t primary_context_id = vt::CutDatabase::get_instance().register_context();

    uint64_t cut_map_id = vt::CutDatabase::get_instance().register_cut(data_world_map_id, view_id, primary_context_id);

    // Registration of resources has to happen before cut update start
    _cut_update = &vt::CutUpdate::get_instance();
    _cut_update->start();

    glfwSetErrorCallback(EventHandler::on_error);

    if(!glfwInit())
    {
        std::runtime_error("GLFW initialisation failed");
    }

    Window *primary_window = create_window(1920, 1080, "First", nullptr, nullptr);
    // TODO
    // create_window(600, 600, "Second", nullptr, primary_window);

    make_context_current(primary_window);

    glfwSwapInterval(1);

    auto *vtrenderer = new vt::VTRenderer(_cut_update);

    vtrenderer->add_data(cut_map_id, data_world_map_id);
    vtrenderer->add_view(view_id, primary_window->_width, primary_window->_height, primary_window->_scale);
    vtrenderer->add_context(primary_context_id);

#ifndef NDEBUG
    glewExperimental = GL_TRUE;

    glewInit();

    ImGui_ImplGlfwGL3_Init(primary_window->_glfw_window, false);

    glEnable(GL_DEBUG_OUTPUT);
    glDebugMessageCallback((GLDEBUGPROC)debug_callback, nullptr);
#endif

    while(!should_close())
    {
        glfwPollEvents();

        for(const auto &window : _windows)
        {
            make_context_current(window);

            if(window == primary_window)
            {
                vtrenderer->update_view(view_id,
                                        window->_width, window->_height,
                                        window->_scale,
                                        window->_trackball_manipulator.transform_matrix());

                vtrenderer->clear_buffers(primary_context_id);

                vtrenderer->render(data_world_map_id, view_id, primary_context_id);

                vtrenderer->collect_feedback(primary_context_id);
#ifndef NDEBUG
                vtrenderer->extract_debug_cut(data_world_map_id, view_id, primary_context_id);
                //vtrenderer->extract_debug_cut(data_world_elevation_id, view_id, primary_context_id);
                vtrenderer->extract_debug_context(primary_context_id);

                ImGui_ImplGlfwGL3_NewFrame();

                vtrenderer->render_debug_cut(data_world_map_id, view_id, primary_context_id);
                //vtrenderer->render_debug_cut(data_world_elevation_id, view_id, primary_context_id);
                vtrenderer->render_debug_context(primary_context_id);

                ImGui::Render();
#endif
            }
            else
            {
                // TODO
            }

            glfwSwapBuffers(window->_glfw_window);
        }
    }

    _cut_update->stop();

    return EXIT_SUCCESS;
}<commit_msg>Replace hardcoded scale factor calculation with function<commit_after>#include "VTRenderer.h"
#include "imgui_impl_glfw_gl3.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <atomic>
#include <condition_variable>
#include <fstream>
#include <lamure/vt/VTConfig.h>
#include <lamure/vt/ren/CutDatabase.h>
#include <lamure/vt/ren/CutUpdate.h>
#include <queue>
#include <unordered_map>

char *get_cmd_option(char **begin, char **end, const std::string &option)
{
    char **it = std::find(begin, end, option);
    if(it != end && ++it != end)
        return *it;
    return nullptr;
}

bool cmd_option_exists(char **begin, char **end, const std::string &option) { return std::find(begin, end, option) != end; }

struct Window
{
    Window()
    {
        _mouse_button_state = MouseButtonState::IDLE;
        _trackball_manipulator.dolly(2.5f);
    }

    unsigned int _width;
    unsigned int _height;

    GLFWwindow *_glfw_window;

    scm::gl::trackball_manipulator _trackball_manipulator;

    float _ref_rot_x;
    float _ref_rot_y;

    float _scale = 0.16f;

    enum MouseButtonState
    {
        LEFT = 0,
        WHEEL = 1,
        RIGHT = 2,
        IDLE = 3
    };

    MouseButtonState _mouse_button_state;
};

std::list<Window *> _windows;
Window *_current_context = nullptr;
vt::CutUpdate *_cut_update = nullptr;

class EventHandler
{
  private:
    static float calculate_factor(float scale)
    {
        return -1.0f/109.0f * scale * scale + 1081.0f/10900.0f * scale + 0.01f;
    }

  public:
    static void on_error(int _err_code, const char *err_msg) { throw std::runtime_error(err_msg); }
    static void on_window_resize(GLFWwindow *glfw_window, int width, int height)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
        window->_height = (uint32_t)height;
        window->_width = (uint32_t)width;
    }
    static void on_window_key_press(GLFWwindow *glfw_window, int key, int scancode, int action, int mods)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
        switch(key)
        {
            case GLFW_KEY_ESCAPE:
                std::cout << "should close" << std::endl;
                glfwSetWindowShouldClose(glfw_window, GL_TRUE);
                break;
            case GLFW_KEY_P:
                if (action == GLFW_PRESS) {
                    _cut_update->set_freeze_dispatch(!_cut_update->get_freeze_dispatch());
                }
                break;
            case GLFW_KEY_RIGHT:
                if (action != GLFW_RELEASE) {
                    window->_trackball_manipulator.translation(-calculate_factor(window->_scale), 0.0f);
                }
                break;
            case GLFW_KEY_LEFT:
                if (action != GLFW_RELEASE) {
                    window->_trackball_manipulator.translation(calculate_factor(window->_scale), 0.0f);
                }
                break;
            case GLFW_KEY_UP:
                if (action != GLFW_RELEASE) {
                    window->_trackball_manipulator.translation(0.0f, -calculate_factor(window->_scale));
                }
                break;
            case GLFW_KEY_DOWN:
                if (action != GLFW_RELEASE) {
                    window->_trackball_manipulator.translation(0.0f, calculate_factor(window->_scale));
                }
                break;
        }

#ifndef NDEBUG
        ImGui_ImplGlfwGL3_KeyCallback(glfw_window, key, scancode, action, mods);
#endif
    }
    static void on_window_char(GLFWwindow *glfw_window, unsigned int codepoint)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
#ifndef NDEBUG
        ImGui_ImplGlfwGL3_CharCallback(glfw_window, codepoint);
#endif
    }
    static void on_window_button_press(GLFWwindow *glfw_window, int button, int action, int mods)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
        if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
        {
            window->_mouse_button_state = Window::MouseButtonState::LEFT;
        }
        else if(button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS)
        {
            window->_mouse_button_state = Window::MouseButtonState::WHEEL;
        }
        else if(button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
        {
            window->_mouse_button_state = Window::MouseButtonState::RIGHT;
        }
        else
        {
            window->_mouse_button_state = Window::MouseButtonState::IDLE;
        }

#ifndef NDEBUG
        ImGui_ImplGlfwGL3_MouseButtonCallback(glfw_window, button, action, mods);
#endif
    }
    static void on_window_move_cursor(GLFWwindow *glfw_window, double xpos, double ypos)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);

        float x = ((float)xpos / window->_width - 0.5f) * 6.28f;
        float y = ((float)ypos / window->_height - 0.5f) * 6.28f;

        switch(window->_mouse_button_state)
        {
        case Window::MouseButtonState::LEFT:
        {
            window->_trackball_manipulator.rotation(window->_ref_rot_x, 0, x, 0);
        }
        break;
        case Window::MouseButtonState::RIGHT:
        {
            window->_trackball_manipulator.rotation(0, window->_ref_rot_y, 0, y);
        }
        break;
        default:
            break;
        }

        window->_ref_rot_x = x;
        window->_ref_rot_y = y;
    }
    static void on_window_scroll(GLFWwindow *glfw_window, double xoffset, double yoffset)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);

        window->_scale = std::max(window->_scale + (float)yoffset * calculate_factor(window->_scale), -0.1f);

#ifndef NDEBUG
        ImGui_ImplGlfwGL3_ScrollCallback(glfw_window, xoffset, yoffset);
#endif
    }
    static void on_window_enter(GLFWwindow *glfw_window, int entered)
    {
        Window *window = (Window *)glfwGetWindowUserPointer(glfw_window);
        // TODO
    }
};

void make_context_current(Window *_window)
{
    if(_window != nullptr)
    {
        glfwMakeContextCurrent(_window->_glfw_window);
        _current_context = _window;
    }
}

Window *create_window(unsigned int width, unsigned int height, const std::string &title, GLFWmonitor *monitor, Window *share)
{
    Window *previous_context = _current_context;

    Window *new_window = new Window();

    new_window->_glfw_window = nullptr;
    new_window->_width = width;
    new_window->_height = height;

    glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, 1);
    glfwWindowHint(GLFW_FOCUSED, 1);
#ifndef NDEBUG
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
#else
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false);
#endif

    if(share != nullptr)
    {
        new_window->_glfw_window = glfwCreateWindow(width, height, title.c_str(), monitor, share->_glfw_window);
    }
    else
    {
        new_window->_glfw_window = glfwCreateWindow(width, height, title.c_str(), monitor, nullptr);
    }

    if(new_window->_glfw_window == nullptr)
    {
        std::runtime_error("GLFW window creation failed");
    }

    make_context_current(new_window);

    glfwSetKeyCallback         (new_window->_glfw_window, &EventHandler::on_window_key_press);
    glfwSetCharCallback        (new_window->_glfw_window, &EventHandler::on_window_char);
    glfwSetMouseButtonCallback (new_window->_glfw_window, &EventHandler::on_window_button_press);
    glfwSetCursorPosCallback   (new_window->_glfw_window, &EventHandler::on_window_move_cursor);
    glfwSetScrollCallback      (new_window->_glfw_window, &EventHandler::on_window_scroll);
    glfwSetCursorEnterCallback (new_window->_glfw_window, &EventHandler::on_window_enter);

    glfwSetWindowUserPointer(new_window->_glfw_window, new_window);

    _windows.push_back(new_window);

    make_context_current(previous_context);

    return new_window;
}

bool should_close()
{
    if(_windows.empty())
        return true;

    std::list<Window *> to_delete;
    for(const auto &window : _windows)
    {
        if(glfwWindowShouldClose(window->_glfw_window))
        {
            to_delete.push_back(window);
        }
    }

    if(!to_delete.empty())
    {
        for(auto &window : to_delete)
        {
            ImGui_ImplGlfwGL3_Shutdown();

            glfwDestroyWindow(window->_glfw_window);

            delete window;

            _windows.remove(window);
        }
    }

    return _windows.empty();
}

void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *param)
{
    switch(severity)
    {
    case GL_DEBUG_SEVERITY_HIGH:
    {
        fprintf(stderr, "GL_DEBUG_SEVERITY_HIGH: %s type = 0x%x, message = %s\n", (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type, message);
    }
    break;
    case GL_DEBUG_SEVERITY_MEDIUM:
    {
        fprintf(stderr, "GL_DEBUG_SEVERITY_MEDIUM: %s type = 0x%x, message = %s\n", (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type, message);
    }
    break;
    case GL_DEBUG_SEVERITY_LOW:
    {
        fprintf(stderr, "GL_DEBUG_SEVERITY_LOW: %s type = 0x%x, message = %s\n", (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type, message);
    }
    break;
    default:
        // ignore
        break;
    }
}

int main(int argc, char *argv[])
{
    vt::VTConfig::CONFIG_PATH = "configuration_template.ini";
    vt::VTConfig::get_instance().define_size_physical_texture(64, 8192);

    uint32_t data_world_map_id = vt::CutDatabase::get_instance().register_dataset(
            "/mnt/terabytes_of_textures/montblanc/montblanc_w1202116_h304384.atlas");

    uint16_t view_id = vt::CutDatabase::get_instance().register_view();
    uint16_t primary_context_id = vt::CutDatabase::get_instance().register_context();

    uint64_t cut_map_id = vt::CutDatabase::get_instance().register_cut(data_world_map_id, view_id, primary_context_id);

    // Registration of resources has to happen before cut update start
    _cut_update = &vt::CutUpdate::get_instance();
    _cut_update->start();

    glfwSetErrorCallback(EventHandler::on_error);

    if(!glfwInit())
    {
        std::runtime_error("GLFW initialisation failed");
    }

    Window *primary_window = create_window(1920, 1080, "First", nullptr, nullptr);
    // TODO
    // create_window(600, 600, "Second", nullptr, primary_window);

    make_context_current(primary_window);

    glfwSwapInterval(1);

    auto *vtrenderer = new vt::VTRenderer(_cut_update);

    vtrenderer->add_data(cut_map_id, data_world_map_id);
    vtrenderer->add_view(view_id, primary_window->_width, primary_window->_height, primary_window->_scale);
    vtrenderer->add_context(primary_context_id);

#ifndef NDEBUG
    glewExperimental = GL_TRUE;

    glewInit();

    ImGui_ImplGlfwGL3_Init(primary_window->_glfw_window, false);

    glEnable(GL_DEBUG_OUTPUT);
    glDebugMessageCallback((GLDEBUGPROC)debug_callback, nullptr);
#endif

    while(!should_close())
    {
        glfwPollEvents();

        for(const auto &window : _windows)
        {
            make_context_current(window);

            if(window == primary_window)
            {
                vtrenderer->update_view(view_id,
                                        window->_width, window->_height,
                                        window->_scale,
                                        window->_trackball_manipulator.transform_matrix());

                vtrenderer->clear_buffers(primary_context_id);

                vtrenderer->render(data_world_map_id, view_id, primary_context_id);

                vtrenderer->collect_feedback(primary_context_id);
#ifndef NDEBUG
                vtrenderer->extract_debug_cut(data_world_map_id, view_id, primary_context_id);
                //vtrenderer->extract_debug_cut(data_world_elevation_id, view_id, primary_context_id);
                vtrenderer->extract_debug_context(primary_context_id);

                ImGui_ImplGlfwGL3_NewFrame();

                vtrenderer->render_debug_cut(data_world_map_id, view_id, primary_context_id);
                //vtrenderer->render_debug_cut(data_world_elevation_id, view_id, primary_context_id);
                vtrenderer->render_debug_context(primary_context_id);

                ImGui::Render();
#endif
            }
            else
            {
                // TODO
            }

            glfwSwapBuffers(window->_glfw_window);
        }
    }

    _cut_update->stop();

    return EXIT_SUCCESS;
}<|endoftext|>