<commit_before>// Copyright (c) 2009 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.

#include "chrome/browser/renderer_host/render_process_host.h"

#include "base/rand_util.h"
#include "base/sys_info.h"
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/common/child_process_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/notification_service.h"

namespace {

size_t GetMaxRendererProcessCount() {
  // Defines the maximum number of renderer processes according to the
  // amount of installed memory as reported by the OS. The table
  // values are calculated by assuming that you want the renderers to
  // use half of the installed ram and assuming that each tab uses
  // ~40MB, however the curve is not linear but piecewise linear with
  // interleaved slopes of 3 and 2.
  // If you modify this table you need to adjust browser\browser_uitest.cc
  // to match the expected number of processes.

  static const size_t kMaxRenderersByRamTier[] = {
    3,                        // less than 256MB
    6,                        //  256MB
    9,                        //  512MB
    12,                       //  768MB
    14,                       // 1024MB
    18,                       // 1280MB
    20,                       // 1536MB
    22,                       // 1792MB
    24,                       // 2048MB
    26,                       // 2304MB
    29,                       // 2560MB
    32,                       // 2816MB
    35,                       // 3072MB
    38,                       // 3328MB
    40                        // 3584MB
  };

  static size_t max_count = 0;
  if (!max_count) {
    size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256;
    if (memory_tier >= arraysize(kMaxRenderersByRamTier))
      max_count = chrome::kMaxRendererProcessCount;
    else
      max_count = kMaxRenderersByRamTier[memory_tier];
  }
  return max_count;
}

// Returns true if the given host is suitable for launching a new view
// associated with the given profile.
static bool IsSuitableHost(RenderProcessHost* host, Profile* profile,
                           RenderProcessHost::Type type) {
  if (host->profile() != profile)
    return false;

  RenderProcessHost::Type host_type = RenderProcessHost::TYPE_NORMAL;
  if (ChildProcessSecurityPolicy::GetInstance()->HasDOMUIBindings(host->id()))
    host_type = RenderProcessHost::TYPE_DOMUI;
  if (ChildProcessSecurityPolicy::GetInstance()->
        HasExtensionBindings(host->id()))
    host_type = RenderProcessHost::TYPE_EXTENSION;

  return host_type == type;
}

// the global list of all renderer processes
IDMap<RenderProcessHost> all_hosts;

}  // namespace

bool RenderProcessHost::run_renderer_in_process_ = false;

RenderProcessHost::RenderProcessHost(Profile* profile)
    : max_page_id_(-1),
      fast_shutdown_started_(false),
      id_(ChildProcessInfo::GenerateChildProcessUniqueId()),
      profile_(profile),
      sudden_termination_allowed_(true),
      ignore_input_events_(false) {
  all_hosts.AddWithID(this, id());
  all_hosts.set_check_on_null_data(true);
}

RenderProcessHost::~RenderProcessHost() {
  all_hosts.Remove(id());
}

void RenderProcessHost::Attach(IPC::Channel::Listener* listener,
                               int routing_id) {
  listeners_.AddWithID(listener, routing_id);
}

void RenderProcessHost::Release(int listener_id) {
  DCHECK(listeners_.Lookup(listener_id) != NULL);
  listeners_.Remove(listener_id);

  // Make sure that all associated resource requests are stopped.
  CancelResourceRequests(listener_id);

  // When no other owners of this object, we can delete ourselves
  if (listeners_.IsEmpty()) {
    NotificationService::current()->Notify(
        NotificationType::RENDERER_PROCESS_TERMINATED,
        Source<RenderProcessHost>(this), NotificationService::NoDetails());
    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
  }
}

void RenderProcessHost::ReportExpectingClose(int32 listener_id) {
  listeners_expecting_close_.insert(listener_id);
}

void RenderProcessHost::UpdateMaxPageID(int32 page_id) {
  if (page_id > max_page_id_)
    max_page_id_ = page_id;
}

bool RenderProcessHost::FastShutdownForPageCount(size_t count) {
  if (listeners_.size() == count)
    return FastShutdownIfPossible();
  return false;
}

// static
RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
  return iterator(&all_hosts);
}

// static
RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
  return all_hosts.Lookup(render_process_id);
}

// static
bool RenderProcessHost::ShouldTryToUseExistingProcessHost() {
  size_t renderer_process_count = all_hosts.size();

  // NOTE: Sometimes it's necessary to create more render processes than
  //       GetMaxRendererProcessCount(), for instance when we want to create
  //       a renderer process for a profile that has no existing renderers.
  //       This is OK in moderation, since the GetMaxRendererProcessCount()
  //       is conservative.

  return run_renderer_in_process() ||
         (renderer_process_count >= GetMaxRendererProcessCount());
}

// static
RenderProcessHost* RenderProcessHost::GetExistingProcessHost(Profile* profile,
                                                             Type type) {
  // First figure out which existing renderers we can use.
  std::vector<RenderProcessHost*> suitable_renderers;
  suitable_renderers.reserve(all_hosts.size());

  iterator iter(AllHostsIterator());
  while (!iter.IsAtEnd()) {
    if (run_renderer_in_process() ||
        IsSuitableHost(iter.GetCurrentValue(), profile, type))
      suitable_renderers.push_back(iter.GetCurrentValue());

    iter.Advance();
  }

  // Now pick a random suitable renderer, if we have any.
  if (!suitable_renderers.empty()) {
    int suitable_count = static_cast<int>(suitable_renderers.size());
    int random_index = base::RandInt(0, suitable_count - 1);
    return suitable_renderers[random_index];
  }

  return NULL;
}
<commit_msg>Remove the RenderProcessHost from the list of renderer processes when we call DeleteSoon, not in the destructor.  Otherewise the process can be reused in the meantime.  This matches what we do in ChildProcessHost.<commit_after>// Copyright (c) 2009 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.

#include "chrome/browser/renderer_host/render_process_host.h"

#include "base/rand_util.h"
#include "base/sys_info.h"
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/common/child_process_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/notification_service.h"

namespace {

size_t GetMaxRendererProcessCount() {
  // Defines the maximum number of renderer processes according to the
  // amount of installed memory as reported by the OS. The table
  // values are calculated by assuming that you want the renderers to
  // use half of the installed ram and assuming that each tab uses
  // ~40MB, however the curve is not linear but piecewise linear with
  // interleaved slopes of 3 and 2.
  // If you modify this table you need to adjust browser\browser_uitest.cc
  // to match the expected number of processes.

  static const size_t kMaxRenderersByRamTier[] = {
    3,                        // less than 256MB
    6,                        //  256MB
    9,                        //  512MB
    12,                       //  768MB
    14,                       // 1024MB
    18,                       // 1280MB
    20,                       // 1536MB
    22,                       // 1792MB
    24,                       // 2048MB
    26,                       // 2304MB
    29,                       // 2560MB
    32,                       // 2816MB
    35,                       // 3072MB
    38,                       // 3328MB
    40                        // 3584MB
  };

  static size_t max_count = 0;
  if (!max_count) {
    size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256;
    if (memory_tier >= arraysize(kMaxRenderersByRamTier))
      max_count = chrome::kMaxRendererProcessCount;
    else
      max_count = kMaxRenderersByRamTier[memory_tier];
  }
  return max_count;
}

// Returns true if the given host is suitable for launching a new view
// associated with the given profile.
static bool IsSuitableHost(RenderProcessHost* host, Profile* profile,
                           RenderProcessHost::Type type) {
  if (host->profile() != profile)
    return false;

  RenderProcessHost::Type host_type = RenderProcessHost::TYPE_NORMAL;
  if (ChildProcessSecurityPolicy::GetInstance()->HasDOMUIBindings(host->id()))
    host_type = RenderProcessHost::TYPE_DOMUI;
  if (ChildProcessSecurityPolicy::GetInstance()->
        HasExtensionBindings(host->id()))
    host_type = RenderProcessHost::TYPE_EXTENSION;

  return host_type == type;
}

// the global list of all renderer processes
IDMap<RenderProcessHost> all_hosts;

}  // namespace

bool RenderProcessHost::run_renderer_in_process_ = false;

RenderProcessHost::RenderProcessHost(Profile* profile)
    : max_page_id_(-1),
      fast_shutdown_started_(false),
      id_(ChildProcessInfo::GenerateChildProcessUniqueId()),
      profile_(profile),
      sudden_termination_allowed_(true),
      ignore_input_events_(false) {
  all_hosts.AddWithID(this, id());
  all_hosts.set_check_on_null_data(true);
}

RenderProcessHost::~RenderProcessHost() {
  // In unit tests, Release() might not have been called.
  if (all_hosts.Lookup(id()))
    all_hosts.Remove(id());
}

void RenderProcessHost::Attach(IPC::Channel::Listener* listener,
                               int routing_id) {
  listeners_.AddWithID(listener, routing_id);
}

void RenderProcessHost::Release(int listener_id) {
  DCHECK(listeners_.Lookup(listener_id) != NULL);
  listeners_.Remove(listener_id);

  // Make sure that all associated resource requests are stopped.
  CancelResourceRequests(listener_id);

  // When no other owners of this object, we can delete ourselves
  if (listeners_.IsEmpty()) {
    NotificationService::current()->Notify(
        NotificationType::RENDERER_PROCESS_TERMINATED,
        Source<RenderProcessHost>(this), NotificationService::NoDetails());
    MessageLoop::current()->DeleteSoon(FROM_HERE, this);

    // Remove ourself from the list of renderer processes so that we can't be
    // reused in between now and when the Delete task runs.
    all_hosts.Remove(id());
  }
}

void RenderProcessHost::ReportExpectingClose(int32 listener_id) {
  listeners_expecting_close_.insert(listener_id);
}

void RenderProcessHost::UpdateMaxPageID(int32 page_id) {
  if (page_id > max_page_id_)
    max_page_id_ = page_id;
}

bool RenderProcessHost::FastShutdownForPageCount(size_t count) {
  if (listeners_.size() == count)
    return FastShutdownIfPossible();
  return false;
}

// static
RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
  return iterator(&all_hosts);
}

// static
RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
  return all_hosts.Lookup(render_process_id);
}

// static
bool RenderProcessHost::ShouldTryToUseExistingProcessHost() {
  size_t renderer_process_count = all_hosts.size();

  // NOTE: Sometimes it's necessary to create more render processes than
  //       GetMaxRendererProcessCount(), for instance when we want to create
  //       a renderer process for a profile that has no existing renderers.
  //       This is OK in moderation, since the GetMaxRendererProcessCount()
  //       is conservative.

  return run_renderer_in_process() ||
         (renderer_process_count >= GetMaxRendererProcessCount());
}

// static
RenderProcessHost* RenderProcessHost::GetExistingProcessHost(Profile* profile,
                                                             Type type) {
  // First figure out which existing renderers we can use.
  std::vector<RenderProcessHost*> suitable_renderers;
  suitable_renderers.reserve(all_hosts.size());

  iterator iter(AllHostsIterator());
  while (!iter.IsAtEnd()) {
    if (run_renderer_in_process() ||
        IsSuitableHost(iter.GetCurrentValue(), profile, type))
      suitable_renderers.push_back(iter.GetCurrentValue());

    iter.Advance();
  }

  // Now pick a random suitable renderer, if we have any.
  if (!suitable_renderers.empty()) {
    int suitable_count = static_cast<int>(suitable_renderers.size());
    int random_index = base::RandInt(0, suitable_count - 1);
    return suitable_renderers[random_index];
  }

  return NULL;
}
<|endoftext|>


<commit_before>/*
    This file is part of KAddressbook.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    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; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <kactioncollection.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kservicetypetrader.h>

#include <QSignalMapper>
#include <QTimer>
#include <ktoggleaction.h>
#include <kvbox.h>

#include "addresseeeditorextension.h"
#include "core.h"
#include "kabprefs.h"

#include "extensionmanager.h"

ExtensionManager::ExtensionManager( KAB::Core *core, QWidget *parent )
  : KHBox( parent ), mCore( core ), mCurrentExtensionWidget( 0 ),
    mMapper( 0 )
{
  createExtensionWidgets();

  mActionCollection = new KActionCollection( this);
  mActionCollection->setObjectName( "ActionCollection" );

  QTimer::singleShot( 0, this, SLOT( createActions() ) );
}

ExtensionManager::~ExtensionManager()
{
}

void ExtensionManager::restoreSettings()
{
  for ( int index = 0; index < mExtensionList.size(); ++index ) {
    ExtensionData data = mExtensionList[ index ];
    if ( data.identifier == KABPrefs::instance()->currentExtension() ) {
      KToggleAction *action = mActionList.size() > index ? static_cast<KToggleAction*>( mActionList.at( index ) ) : 0;
      if ( action )
        action->setChecked( true );
      setActiveExtension( index );
      return;
    }
  }

  if ( mActionList.first() )
    static_cast<KToggleAction*>( mActionList.first() )->setChecked( true );
  setActiveExtension( 0 );
}

void ExtensionManager::saveSettings()
{
  QAction *action;
  int index = 0;
  for (int i = 0; i < mActionList.size(); ++i) {
    action = mActionList.at(i);
    if ( static_cast<KToggleAction*>( action )->isChecked() ) {
      index = i;
      break;
    }
  }
  Q_ASSERT( index < mExtensionList.size() );

  KABPrefs::instance()->setCurrentExtension( mExtensionList[ index ].identifier );
}

void ExtensionManager::reconfigure()
{
  saveSettings();
  createExtensionWidgets();
  createActions();
  restoreSettings();
}

bool ExtensionManager::isQuickEditVisible() const
{
  return ( mCurrentExtensionWidget &&
      mCurrentExtensionWidget->identifier() == "contact_editor" );
}

void ExtensionManager::setSelectionChanged()
{
  if ( mCurrentExtensionWidget )
    mCurrentExtensionWidget->contactsSelectionChanged();
}

void ExtensionManager::setActiveExtension( int id )
{
  if ( id == 0 ) {
    hide();
    if ( mCurrentExtensionWidget )
      mCurrentExtensionWidget->hide();
    mCurrentExtensionWidget = 0;
  } else if ( id > 0 ) {
    if ( mCurrentExtensionWidget )
      mCurrentExtensionWidget->hide();

    mCurrentExtensionWidget = mExtensionList[ id ].widget;
    if ( mCurrentExtensionWidget ) {
      show();
      mCurrentExtensionWidget->show();
      mCurrentExtensionWidget->contactsSelectionChanged();
    } else {
      hide();
      mCurrentExtensionWidget = 0;
    }
  }
}

void ExtensionManager::createActions()
{
  mCore->guiClient()->unplugActionList( "extensions_list" );
  qDeleteAll( mActionList );
  mActionList.clear();

  delete mMapper;
  mMapper = new QSignalMapper( this );
  mMapper->setObjectName( "SignalMapper" );
  connect( mMapper, SIGNAL( mapped( int ) ),
           this, SLOT( setActiveExtension( int ) ) );

  int actionCounter = 0;
  ExtensionData::List::ConstIterator it;
  QActionGroup* extensionGroup = new QActionGroup(this);
  for ( it = mExtensionList.begin(); it != mExtensionList.end(); ++it ) {
    ExtensionData data = *it;
    KToggleAction *action = mActionCollection->add<KToggleAction>( QString( data.identifier + "_extension" ) );
    action->setText( data.title );
    connect(action, SIGNAL(triggered(bool) ), mMapper, SLOT( map() ));
    action->setActionGroup( extensionGroup );
    mMapper->setMapping( action, actionCounter++ );
    mActionList.append( action );

    if ( data.widget == mCurrentExtensionWidget )
      action->setChecked( true );
  }

  mCore->guiClient()->plugActionList( "extensions_list", mActionList );

  if ( mCurrentExtensionWidget == 0 && mActionList.first() )
    static_cast<KToggleAction*>( mActionList.first() )->setChecked( true );
}

void ExtensionManager::createExtensionWidgets()
{
  // clean up
  ExtensionData::List::ConstIterator dataIt;
  for ( dataIt = mExtensionList.begin(); dataIt != mExtensionList.end(); ++dataIt )
    delete (*dataIt).widget;
  mExtensionList.clear();

  KAB::ExtensionWidget *wdg = 0;

  {
    // add 'None' entry
    ExtensionData data;
    data.identifier = "none";
    data.title = i18n( "None" );
    data.widget = 0;
    mExtensionList.append( data );
  }

  {
    // add addressee editor as default
    wdg = new AddresseeEditorExtension( mCore, this );
    wdg->hide();

    connect( wdg, SIGNAL( modified( const KABC::Addressee::List& ) ),
             SIGNAL( modified( const KABC::Addressee::List& ) ) );
    connect( wdg, SIGNAL( deleted( const QStringList& ) ),
             SIGNAL( deleted( const QStringList& ) ) );

    ExtensionData data;
    data.identifier = wdg->identifier();
    data.title = wdg->title();
    data.widget = wdg;
    mExtensionList.append( data );
  }

  // load the other extensions
  const KService::List plugins = KServiceTypeTrader::self()->query( "KAddressBook/Extension",
    QString( "[X-KDE-KAddressBook-ExtensionPluginVersion] == %1" ).arg( KAB_EXTENSIONWIDGET_PLUGIN_VERSION ) );

  KService::List::ConstIterator it;
  for ( it = plugins.begin(); it != plugins.end(); ++it ) {
    KLibFactory *factory = KLibLoader::self()->factory( (*it)->library().toLatin1() );
    if ( !factory ) {
      kDebug(5720) <<"ExtensionManager::loadExtensions(): Factory creation failed";
      continue;
    }

    KAB::ExtensionFactory *extensionFactory = static_cast<KAB::ExtensionFactory*>( factory );

    if ( !extensionFactory ) {
      kDebug(5720) <<"ExtensionManager::loadExtensions(): Cast failed";
      continue;
    }

    wdg = extensionFactory->extension( mCore, this );
    if ( wdg ) {
      wdg->hide();
      connect( wdg, SIGNAL( modified( const KABC::Addressee::List& ) ),
               SIGNAL( modified( const KABC::Addressee::List& ) ) );
      connect( wdg, SIGNAL( deleted( const QStringList& ) ),
               SIGNAL( deleted( const QStringList& ) ) );

      ExtensionData data;
      data.identifier = wdg->identifier();
      data.title = wdg->title();
      data.widget = wdg;
      mExtensionList.append( data );
    }
  }

  mCurrentExtensionWidget = 0;
}

#include "extensionmanager.moc"
<commit_msg>- Fixed crash: QList::first() asserts on empty lists. Probably a porting issue,   Qt3 QPtrList::first() did just return 0 in such cases.<commit_after>/*
    This file is part of KAddressbook.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    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; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <kactioncollection.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kservicetypetrader.h>

#include <QSignalMapper>
#include <QTimer>
#include <ktoggleaction.h>
#include <kvbox.h>

#include "addresseeeditorextension.h"
#include "core.h"
#include "kabprefs.h"

#include "extensionmanager.h"

ExtensionManager::ExtensionManager( KAB::Core *core, QWidget *parent )
  : KHBox( parent ), mCore( core ), mCurrentExtensionWidget( 0 ),
    mMapper( 0 )
{
  createExtensionWidgets();

  mActionCollection = new KActionCollection( this);
  mActionCollection->setObjectName( "ActionCollection" );

  QTimer::singleShot( 0, this, SLOT( createActions() ) );
}

ExtensionManager::~ExtensionManager()
{
}

void ExtensionManager::restoreSettings()
{
  for ( int index = 0; index < mExtensionList.size(); ++index ) {
    ExtensionData data = mExtensionList[ index ];
    if ( data.identifier == KABPrefs::instance()->currentExtension() ) {
      KToggleAction *action = mActionList.size() > index ? static_cast<KToggleAction*>( mActionList.at( index ) ) : 0;
      if ( action )
        action->setChecked( true );
      setActiveExtension( index );
      return;
    }
  }

  if ( !mActionList.isEmpty() && mActionList.first() )
    static_cast<KToggleAction*>( mActionList.first() )->setChecked( true );
  setActiveExtension( 0 );
}

void ExtensionManager::saveSettings()
{
  QAction *action;
  int index = 0;
  for (int i = 0; i < mActionList.size(); ++i) {
    action = mActionList.at(i);
    if ( static_cast<KToggleAction*>( action )->isChecked() ) {
      index = i;
      break;
    }
  }
  Q_ASSERT( index < mExtensionList.size() );

  KABPrefs::instance()->setCurrentExtension( mExtensionList[ index ].identifier );
}

void ExtensionManager::reconfigure()
{
  saveSettings();
  createExtensionWidgets();
  createActions();
  restoreSettings();
}

bool ExtensionManager::isQuickEditVisible() const
{
  return ( mCurrentExtensionWidget &&
      mCurrentExtensionWidget->identifier() == "contact_editor" );
}

void ExtensionManager::setSelectionChanged()
{
  if ( mCurrentExtensionWidget )
    mCurrentExtensionWidget->contactsSelectionChanged();
}

void ExtensionManager::setActiveExtension( int id )
{
  if ( id == 0 ) {
    hide();
    if ( mCurrentExtensionWidget )
      mCurrentExtensionWidget->hide();
    mCurrentExtensionWidget = 0;
  } else if ( id > 0 ) {
    if ( mCurrentExtensionWidget )
      mCurrentExtensionWidget->hide();

    mCurrentExtensionWidget = mExtensionList[ id ].widget;
    if ( mCurrentExtensionWidget ) {
      show();
      mCurrentExtensionWidget->show();
      mCurrentExtensionWidget->contactsSelectionChanged();
    } else {
      hide();
      mCurrentExtensionWidget = 0;
    }
  }
}

void ExtensionManager::createActions()
{
  mCore->guiClient()->unplugActionList( "extensions_list" );
  qDeleteAll( mActionList );
  mActionList.clear();

  delete mMapper;
  mMapper = new QSignalMapper( this );
  mMapper->setObjectName( "SignalMapper" );
  connect( mMapper, SIGNAL( mapped( int ) ),
           this, SLOT( setActiveExtension( int ) ) );

  int actionCounter = 0;
  ExtensionData::List::ConstIterator it;
  QActionGroup* extensionGroup = new QActionGroup(this);
  for ( it = mExtensionList.begin(); it != mExtensionList.end(); ++it ) {
    ExtensionData data = *it;
    KToggleAction *action = mActionCollection->add<KToggleAction>( QString( data.identifier + "_extension" ) );
    action->setText( data.title );
    connect(action, SIGNAL(triggered(bool) ), mMapper, SLOT( map() ));
    action->setActionGroup( extensionGroup );
    mMapper->setMapping( action, actionCounter++ );
    mActionList.append( action );

    if ( data.widget == mCurrentExtensionWidget )
      action->setChecked( true );
  }

  mCore->guiClient()->plugActionList( "extensions_list", mActionList );

  if ( mCurrentExtensionWidget == 0 && !mActionList.isEmpty() && mActionList.first() )
    static_cast<KToggleAction*>( mActionList.first() )->setChecked( true );
}

void ExtensionManager::createExtensionWidgets()
{
  // clean up
  ExtensionData::List::ConstIterator dataIt;
  for ( dataIt = mExtensionList.begin(); dataIt != mExtensionList.end(); ++dataIt )
    delete (*dataIt).widget;
  mExtensionList.clear();

  KAB::ExtensionWidget *wdg = 0;

  {
    // add 'None' entry
    ExtensionData data;
    data.identifier = "none";
    data.title = i18n( "None" );
    data.widget = 0;
    mExtensionList.append( data );
  }

  {
    // add addressee editor as default
    wdg = new AddresseeEditorExtension( mCore, this );
    wdg->hide();

    connect( wdg, SIGNAL( modified( const KABC::Addressee::List& ) ),
             SIGNAL( modified( const KABC::Addressee::List& ) ) );
    connect( wdg, SIGNAL( deleted( const QStringList& ) ),
             SIGNAL( deleted( const QStringList& ) ) );

    ExtensionData data;
    data.identifier = wdg->identifier();
    data.title = wdg->title();
    data.widget = wdg;
    mExtensionList.append( data );
  }

  // load the other extensions
  const KService::List plugins = KServiceTypeTrader::self()->query( "KAddressBook/Extension",
    QString( "[X-KDE-KAddressBook-ExtensionPluginVersion] == %1" ).arg( KAB_EXTENSIONWIDGET_PLUGIN_VERSION ) );

  KService::List::ConstIterator it;
  for ( it = plugins.begin(); it != plugins.end(); ++it ) {
    KLibFactory *factory = KLibLoader::self()->factory( (*it)->library().toLatin1() );
    if ( !factory ) {
      kDebug(5720) <<"ExtensionManager::loadExtensions(): Factory creation failed";
      continue;
    }

    KAB::ExtensionFactory *extensionFactory = static_cast<KAB::ExtensionFactory*>( factory );

    if ( !extensionFactory ) {
      kDebug(5720) <<"ExtensionManager::loadExtensions(): Cast failed";
      continue;
    }

    wdg = extensionFactory->extension( mCore, this );
    if ( wdg ) {
      wdg->hide();
      connect( wdg, SIGNAL( modified( const KABC::Addressee::List& ) ),
               SIGNAL( modified( const KABC::Addressee::List& ) ) );
      connect( wdg, SIGNAL( deleted( const QStringList& ) ),
               SIGNAL( deleted( const QStringList& ) ) );

      ExtensionData data;
      data.identifier = wdg->identifier();
      data.title = wdg->title();
      data.widget = wdg;
      mExtensionList.append( data );
    }
  }

  mCurrentExtensionWidget = 0;
}

#include "extensionmanager.moc"
<|endoftext|>


<commit_before>/*
    Copyright 2009 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 28/10/09.

    This file is part of MRtrix.

    MRtrix 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 3 of the License, or
    (at your option) any later version.

    MRtrix 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 MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "command.h"
#include "point.h"
#include "math/SH.h"
#include "image/buffer.h"
#include "image/voxel.h"
#include "math/vector.h"
#include "image/loop.h"

using namespace MR;
using namespace App;

void usage () {
  DESCRIPTION
    + "generate a planar ROI.";

  ARGUMENTS
    + Argument ("point1",
        "a point on the plane, supplied as comma-separated "
        "3-vector of floating-point values, corresponding to the real/scanner "
        "coordinates of the point in mm.")
    .type_sequence_float()

    + Argument ("point2",
        "a point on the plane, supplied as comma-separated "
        "3-vector of floating-point values, corresponding to the real/scanner "
        "coordinates of the point in mm.")
    .type_sequence_float()

    + Argument ("point3",
        "a point on the plane, supplied as comma-separated "
        "3-vector of floating-point values, corresponding to the real/scanner "
        "coordinates of the point in mm.")
    .type_sequence_float()

    + Argument ("template",
        "a template image used to compute the required extent of the ROI.")
    .type_image_in()

    + Argument ("ROI", "the output ROI image.").type_image_out();

  OPTIONS
    + Option ("vox",
        "the desired (isotropic) voxel size (default is same as template).")
    + Argument ("size").type_float (0.0, 00.0, std::numeric_limits<float>::max());
}

inline Point<> get_bounds (const Point<>& corner, const Point<>& axis, const Point<>& ref, const Point<>& d1, const Point<>& d2) {
  Math::Matrix<float> M(3,3);
  Math::Vector<float> X(3);

  M(0,0) = d1[0]; M(0,1) = d2[0]; M(0,2) = axis[0];
  M(1,0) = d1[1]; M(1,1) = d2[1]; M(1,2) = axis[1];
  M(2,0) = d1[2]; M(2,1) = d2[2]; M(2,2) = axis[2];

  X[0] = corner[0] - ref[0];
  X[1] = corner[1] - ref[1];
  X[2] = corner[2] - ref[2];

  Math::Permutation p (3);
  int signum;
  Math::LU::decomp (M, p, signum);
  Math::LU::solve (X, M, p);

  return Point<> (X[0], X[1], X[2]);
}

inline Point<> get_bounds (const Image::Header& header, Point<int> corner, int axis, const Point<>& ref, const Point<>& d1, const Point<>& d2) {
  const Math::Matrix<float>& T (header.transform());
  Point<> pos (T(0,3), T(1,3), T(2,3));
  for (size_t n = 0; n < 3; ++n)
    if (corner[n])
      pos += header.dim(n) * header.vox(n) * Point<> (T(0,n), T(1,n), T(2,n));
  Point<> dir (T(0,axis), T(1,axis), T(2,axis));
  Point<> ret = get_bounds (pos, dir, ref, d1, d2);
  ret[2] /= -header.vox (axis) * header.dim (axis);
  return ret;
}

inline void update_bounds (float& min1, float& min2, float& max1, float& max2, const Image::Header& header, Point<int> corner, int axis, const Point<>& ref, const Point<>& d1, const Point<>& d2) {
  Point<> bound = get_bounds (header, corner, axis, ref, d1, d2);
  if (bound[2] >= 0.0 && bound[2] <= 1.0) {
    if (min1 > bound[0]) min1 = bound[0];
    if (min2 > bound[1]) min2 = bound[1];
    if (max1 < bound[0]) max1 = bound[0];
    if (max2 < bound[1]) max2 = bound[1];
  }
}

void run () {
  Point<> p[3];
  for (size_t arg = 0; arg < 3; ++arg) {
    std::vector<float> V = argument[arg];
    if (V.size() != 3)
      throw Exception ("coordinates must contain 3 elements");
    p[arg][0] = V[0];
    p[arg][1] = V[1];
    p[arg][2] = V[2];
  }

  Image::Header header (argument[3]);
  float vox = std::pow (header.vox(0)*header.vox(1)*header.vox(2), 1.0f/3.0f);
  Options opt = get_options ("vox");
  if (opt.size())
    vox = opt[0][0];

  Point<> d1 = p[1] - p[0];
  Point<> d2 = p[2] - p[0];
  d1.normalise();
  d2.normalise();

  d2 = d2 - d1 * d1.dot(d2);
  d2.normalise();

  Point<> d3 = d1.cross(d2);

  float min1 = std::numeric_limits<float>::infinity();
  float min2 = std::numeric_limits<float>::infinity();
  float max1 = -std::numeric_limits<float>::infinity();
  float max2 = -std::numeric_limits<float>::infinity();

  update_bounds (min1, min2, max1, max2, header, Point<int>(0,0,0), 0, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(0,0,0), 1, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(0,0,0), 2, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(1,0,0), 1, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(1,0,0), 2, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(0,1,0), 0, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(0,1,0), 2, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(0,0,1), 0, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(0,0,1), 1, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(1,1,0), 2, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(1,0,1), 1, p[0], d1, d2);
  update_bounds (min1, min2, max1, max2, header, Point<int>(0,1,1), 0, p[0], d1, d2);

  Point<> translation (p[0] + min1*d1 + min2*d2);

  header.transform()(0,0) = d1[0];
  header.transform()(1,0) = d1[1];
  header.transform()(2,0) = d1[2];

  header.transform()(0,1) = d2[0];
  header.transform()(1,1) = d2[1];
  header.transform()(2,1) = d2[2];

  header.transform()(0,2) = d3[0];
  header.transform()(1,2) = d3[1];
  header.transform()(2,2) = d3[2];

  header.transform()(0,3) = translation[0];
  header.transform()(1,3) = translation[1];
  header.transform()(2,3) = translation[2];

  header.set_ndim (3);
  header.dim (0) = (max1-min1) / vox;
  header.dim (1) = (max2-min2) / vox;
  header.dim (2) = 1;

  header.vox(0) = header.vox(1) = header.vox(2) = vox;

  header.datatype() = DataType::Bit;
  header.DW_scheme().clear();

  Image::Buffer<bool> roi_buffer (argument[4], header);
  auto roi = roi_buffer.voxel();
  for (auto i = Image::LoopInOrder (roi) (roi); i; ++i)
    roi.value() = true;

}

<commit_msg>removed roigen command<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: editsrc.hxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 17:38:09 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_EDITSRC_HXX
#define SC_EDITSRC_HXX

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

#ifndef _SVX_UNOEDSRC_HXX
#include <svx/unoedsrc.hxx>
#endif

#ifndef _SFXLSTNER_HXX //autogen
#include <svtools/lstner.hxx>
#endif

#include <memory>

class ScEditEngineDefaulter;
class SvxEditEngineForwarder;

class ScDocShell;
class ScHeaderFooterContentObj;
class ScCellTextData;
class ScHeaderFooterTextData;
class ScAccessibleTextData;
class SdrObject;

class ScHeaderFooterChangedHint : public SfxHint
{
    USHORT nPart;

public:
                    TYPEINFO();
                    ScHeaderFooterChangedHint(USHORT nP);
                    ~ScHeaderFooterChangedHint();

    USHORT          GetPart() const         { return nPart; }
};

//  all ScSharedHeaderFooterEditSource objects for a single text share the same data

class ScSharedHeaderFooterEditSource : public SvxEditSource
{
private:
    ScHeaderFooterTextData*     pTextData;

protected:
    ScHeaderFooterTextData*     GetTextData() const { return pTextData; }   // for ScHeaderFooterEditSource

public:
                                ScSharedHeaderFooterEditSource( ScHeaderFooterTextData* pData );
    virtual                     ~ScSharedHeaderFooterEditSource();

    //  GetEditEngine is needed because the forwarder doesn't have field functions
    ScEditEngineDefaulter*      GetEditEngine();

    virtual SvxEditSource*      Clone() const ;
    virtual SvxTextForwarder*   GetTextForwarder();

    virtual void                UpdateData();

};

//  ScHeaderFooterEditSource with local copy of ScHeaderFooterTextData is used by field objects

class ScHeaderFooterEditSource : public ScSharedHeaderFooterEditSource
{
public:
                                ScHeaderFooterEditSource( ScHeaderFooterContentObj* pContent, USHORT nP );
                                ScHeaderFooterEditSource( ScHeaderFooterContentObj& rContent, USHORT nP );
    virtual                     ~ScHeaderFooterEditSource();

    virtual SvxEditSource*      Clone() const;
};

//  Data (incl. EditEngine) for cell EditSource is now shared in ScCellTextData

class ScSharedCellEditSource : public SvxEditSource
{
private:
    ScCellTextData*         pCellTextData;

protected:
    ScCellTextData*         GetCellTextData() const { return pCellTextData; }   // for ScCellEditSource

public:
                                ScSharedCellEditSource( ScCellTextData* pData );
    virtual                     ~ScSharedCellEditSource();

    //  GetEditEngine is needed because the forwarder doesn't have field functions
    ScEditEngineDefaulter*      GetEditEngine();

    virtual SvxEditSource*      Clone() const;
    virtual SvxTextForwarder*   GetTextForwarder();

    virtual void                UpdateData();

    void                        SetDoUpdateData(sal_Bool bValue);
    sal_Bool                    IsDirty() const;
};

//  ScCellEditSource with local copy of ScCellTextData is used by ScCellFieldsObj, ScCellFieldObj

class ScCellEditSource : public ScSharedCellEditSource
{
public:
                                ScCellEditSource( ScDocShell* pDocSh, const ScAddress& rP );
    virtual                     ~ScCellEditSource();

    virtual SvxEditSource*      Clone() const;
};

class ScAnnotationEditSource : public SvxEditSource, public SfxListener
{
private:
    ScDocShell*             pDocShell;
    ScAddress               aCellPos;
    ScEditEngineDefaulter*  pEditEngine;
    SvxEditEngineForwarder* pForwarder;
    BOOL                    bDataValid;

    SdrObject*                  GetCaptionObj();
public:
                                ScAnnotationEditSource(ScDocShell* pDocSh, const ScAddress& rP);
    virtual                     ~ScAnnotationEditSource();

    virtual SvxEditSource*      Clone() const ;
    virtual SvxTextForwarder*   GetTextForwarder();
    virtual void                UpdateData();

    virtual void                Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
};

//  EditSource with a shared forwarder for all children of one text object

class ScSimpleEditSource : public SvxEditSource
{
private:
    SvxTextForwarder*   pForwarder;

public:
                        ScSimpleEditSource( SvxTextForwarder* pForw );
    virtual             ~ScSimpleEditSource();

    virtual SvxEditSource*      Clone() const ;
    virtual SvxTextForwarder*   GetTextForwarder();
    virtual void                UpdateData();

};

class ScAccessibilityEditSource : public SvxEditSource
{
private:
    ::std::auto_ptr < ScAccessibleTextData > mpAccessibleTextData;

public:
                        ScAccessibilityEditSource( ::std::auto_ptr < ScAccessibleTextData > pAccessibleCellTextData );
    virtual             ~ScAccessibilityEditSource();

    virtual SvxEditSource*      Clone() const;
    virtual SvxTextForwarder*   GetTextForwarder();
    virtual SvxViewForwarder*   GetViewForwarder();
    virtual SvxEditViewForwarder*   GetEditViewForwarder( sal_Bool bCreate = sal_False );
    virtual void                UpdateData();
    virtual SfxBroadcaster&     GetBroadcaster() const;

    void                        SetDoUpdateData(sal_Bool bValue);
    sal_Bool                    IsDirty() const;
};

#endif

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

#ifndef SC_EDITSRC_HXX
#define SC_EDITSRC_HXX

#include "address.hxx"
#include <svx/unoedsrc.hxx>
#include <svtools/lstner.hxx>

#include <memory>

class ScEditEngineDefaulter;
class SvxEditEngineForwarder;

class ScDocShell;
class ScHeaderFooterContentObj;
class ScCellTextData;
class ScHeaderFooterTextData;
class ScAccessibleTextData;
class SdrObject;

class ScHeaderFooterChangedHint : public SfxHint
{
    USHORT nPart;

public:
                    TYPEINFO();
                    ScHeaderFooterChangedHint(USHORT nP);
                    ~ScHeaderFooterChangedHint();

    USHORT          GetPart() const         { return nPart; }
};

//  all ScSharedHeaderFooterEditSource objects for a single text share the same data

class ScSharedHeaderFooterEditSource : public SvxEditSource
{
private:
    ScHeaderFooterTextData*     pTextData;

protected:
    ScHeaderFooterTextData*     GetTextData() const { return pTextData; }   // for ScHeaderFooterEditSource

public:
                                ScSharedHeaderFooterEditSource( ScHeaderFooterTextData* pData );
    virtual                     ~ScSharedHeaderFooterEditSource();

    //  GetEditEngine is needed because the forwarder doesn't have field functions
    ScEditEngineDefaulter*      GetEditEngine();

    virtual SvxEditSource*      Clone() const ;
    virtual SvxTextForwarder*   GetTextForwarder();

    virtual void                UpdateData();

};

//  ScHeaderFooterEditSource with local copy of ScHeaderFooterTextData is used by field objects

class ScHeaderFooterEditSource : public ScSharedHeaderFooterEditSource
{
public:
                                ScHeaderFooterEditSource( ScHeaderFooterContentObj* pContent, USHORT nP );
                                ScHeaderFooterEditSource( ScHeaderFooterContentObj& rContent, USHORT nP );
    virtual                     ~ScHeaderFooterEditSource();

    virtual SvxEditSource*      Clone() const;
};

//  Data (incl. EditEngine) for cell EditSource is now shared in ScCellTextData

class ScSharedCellEditSource : public SvxEditSource
{
private:
    ScCellTextData*         pCellTextData;

protected:
    ScCellTextData*         GetCellTextData() const { return pCellTextData; }   // for ScCellEditSource

public:
                                ScSharedCellEditSource( ScCellTextData* pData );
    virtual                     ~ScSharedCellEditSource();

    //  GetEditEngine is needed because the forwarder doesn't have field functions
    ScEditEngineDefaulter*      GetEditEngine();

    virtual SvxEditSource*      Clone() const;
    virtual SvxTextForwarder*   GetTextForwarder();

    virtual void                UpdateData();

    void                        SetDoUpdateData(sal_Bool bValue);
    sal_Bool                    IsDirty() const;
};

//  ScCellEditSource with local copy of ScCellTextData is used by ScCellFieldsObj, ScCellFieldObj

class ScCellEditSource : public ScSharedCellEditSource
{
public:
                                ScCellEditSource( ScDocShell* pDocSh, const ScAddress& rP );
    virtual                     ~ScCellEditSource();

    virtual SvxEditSource*      Clone() const;
};

class ScAnnotationEditSource : public SvxEditSource, public SfxListener
{
private:
    ScDocShell*             pDocShell;
    ScAddress               aCellPos;
    ScEditEngineDefaulter*  pEditEngine;
    SvxEditEngineForwarder* pForwarder;
    BOOL                    bDataValid;

    SdrObject*                  GetCaptionObj();
public:
                                ScAnnotationEditSource(ScDocShell* pDocSh, const ScAddress& rP);
    virtual                     ~ScAnnotationEditSource();

    virtual SvxEditSource*      Clone() const ;
    virtual SvxTextForwarder*   GetTextForwarder();
    virtual void                UpdateData();

    virtual void                Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
};

//  EditSource with a shared forwarder for all children of one text object

class ScSimpleEditSource : public SvxEditSource
{
private:
    SvxTextForwarder*   pForwarder;

public:
                        ScSimpleEditSource( SvxTextForwarder* pForw );
    virtual             ~ScSimpleEditSource();

    virtual SvxEditSource*      Clone() const ;
    virtual SvxTextForwarder*   GetTextForwarder();
    virtual void                UpdateData();

};

class ScAccessibilityEditSource : public SvxEditSource
{
private:
    ::std::auto_ptr < ScAccessibleTextData > mpAccessibleTextData;

public:
                        ScAccessibilityEditSource( ::std::auto_ptr < ScAccessibleTextData > pAccessibleCellTextData );
    virtual             ~ScAccessibilityEditSource();

    virtual SvxEditSource*      Clone() const;
    virtual SvxTextForwarder*   GetTextForwarder();
    virtual SvxViewForwarder*   GetViewForwarder();
    virtual SvxEditViewForwarder*   GetEditViewForwarder( sal_Bool bCreate = sal_False );
    virtual void                UpdateData();
    virtual SfxBroadcaster&     GetBroadcaster() const;

    void                        SetDoUpdateData(sal_Bool bValue);
    sal_Bool                    IsDirty() const;
};

#endif

<|endoftext|>


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

#include "include/wrapper/cef_byte_read_handler.h"
#include <stdlib.h>
#include "libcef_dll/cef_logging.h"

CefByteReadHandler::CefByteReadHandler(const unsigned char* bytes, size_t size,
                                       CefRefPtr<CefBase> source)
  : bytes_(bytes), size_(size), offset_(0), source_(source) {
}

size_t CefByteReadHandler::Read(void* ptr, size_t size, size_t n) {
  AutoLock lock_scope(this);
  size_t s = (size_ - offset_) / size;
  size_t ret = std::min(n, s);
  memcpy(ptr, bytes_ + offset_, ret * size);
  offset_ += ret * size;
  return ret;
}

int CefByteReadHandler::Seek(int64 offset, int whence) {
  int rv = -1L;
  AutoLock lock_scope(this);
  switch (whence) {
  case SEEK_CUR:
    if (offset_ + offset > size_ || offset_ + offset < 0)
      break;
    offset_ += offset;
    rv = 0;
    break;
  case SEEK_END: {
    int64 offset_abs = abs(offset);
    if (offset_abs > size_)
      break;
    offset_ = size_ - offset_abs;
    rv = 0;
    break;
  }
  case SEEK_SET:
    if (offset > size_ || offset < 0)
      break;
    offset_ = offset;
    rv = 0;
    break;
  }

  return rv;
}

int64 CefByteReadHandler::Tell() {
  AutoLock lock_scope(this);
  return offset_;
}

int CefByteReadHandler::Eof() {
  AutoLock lock_scope(this);
  return (offset_ >= size_);
}
<commit_msg>Fix compile warning in CefByteReadHandler::Read.<commit_after>// Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "include/wrapper/cef_byte_read_handler.h"
#include <stdlib.h>
#include "libcef_dll/cef_logging.h"

CefByteReadHandler::CefByteReadHandler(const unsigned char* bytes, size_t size,
                                       CefRefPtr<CefBase> source)
  : bytes_(bytes), size_(size), offset_(0), source_(source) {
}

size_t CefByteReadHandler::Read(void* ptr, size_t size, size_t n) {
  AutoLock lock_scope(this);
  size_t s = static_cast<size_t>(size_ - offset_) / size;
  size_t ret = std::min(n, s);
  memcpy(ptr, bytes_ + offset_, ret * size);
  offset_ += ret * size;
  return ret;
}

int CefByteReadHandler::Seek(int64 offset, int whence) {
  int rv = -1L;
  AutoLock lock_scope(this);
  switch (whence) {
  case SEEK_CUR:
    if (offset_ + offset > size_ || offset_ + offset < 0)
      break;
    offset_ += offset;
    rv = 0;
    break;
  case SEEK_END: {
    int64 offset_abs = abs(offset);
    if (offset_abs > size_)
      break;
    offset_ = size_ - offset_abs;
    rv = 0;
    break;
  }
  case SEEK_SET:
    if (offset > size_ || offset < 0)
      break;
    offset_ = offset;
    rv = 0;
    break;
  }

  return rv;
}

int64 CefByteReadHandler::Tell() {
  AutoLock lock_scope(this);
  return offset_;
}

int CefByteReadHandler::Eof() {
  AutoLock lock_scope(this);
  return (offset_ >= size_);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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.
#include "ceee/ie/plugin/toolband/toolband_proxy.h"

#include <atlbase.h>
#include "base/logging.h"
#include "base/stringprintf.h"
#include "base/win/registry.h"
#include "ceee/common/com_utils.h"
#include "ceee/ie/plugin/toolband/resource.h"

#include "toolband.h"  // NOLINT

extern "C" {
// Declare the entrypoint function(s) generated by MIDL for our proxy/stubs.
HRESULT STDAPICALLTYPE ToolbandProxyDllGetClassObject(REFCLSID clsid,
                                                      REFIID iid,
                                                      void** ppv);
}  // extern "C"

namespace {

struct InterfaceInfo {
  const wchar_t* name;
  const IID* iid;
  const IID* async_iid;
};

#define DECLARE_SYNC_INTERFACE(itf) \
  { L#itf, &IID_##itf, NULL },
#define DECLARE_ASYNC_INTERFACE(itf) \
  { L#itf, &IID_##itf, &IID_Async##itf }, \
  DECLARE_SYNC_INTERFACE(Async##itf)

// If you add new executor interfaces to toolband.idl, make sure to add
// their IIDs here, or you will not be able to marshal them.
const InterfaceInfo kInterfaceInfo[] = {
  DECLARE_SYNC_INTERFACE(ICeeeWindowExecutor)
  DECLARE_ASYNC_INTERFACE(ICeeeTabExecutor)
  DECLARE_SYNC_INTERFACE(ICeeeCookieExecutor)
  DECLARE_SYNC_INTERFACE(ICeeeInfobarExecutor)
};

#ifndef NDEBUG
void CheckAsyncIidRegistered(const IID& iid, const IID& async_iid) {
  std::wstring iid_str;
  bool success = com::GuidToString(iid, &iid_str);
  DCHECK(success);
  std::wstring key_name = base::StringPrintf(
      L"Interface\\%ls\\AsynchronousInterface", iid_str);

  base::win::RegKey key;
  if (key.Open(HKEY_CLASSES_ROOT, key_name.c_str(), KEY_READ)) {
    // It's registered, the rest of this block is debug checking that
    // the correct IID is indeed registered for the async interface.
    std::wstring async_iid_str;
    DCHECK(key.ReadValue(NULL, &async_iid_str));
    IID read_async_iid;
    DCHECK(SUCCEEDED(::IIDFromString(async_iid_str.c_str(), &read_async_iid)));
    DCHECK(read_async_iid == async_iid);
  } else {
    LOG(WARNING) << "Sync->Async IID not registered. Key=" << key_name;
  }
}
#endif  // NDEBUG

}  // namespace

bool RegisterProxyStubs(std::vector<DWORD>* cookies) {
  bool succeeded = true;

  for (size_t i = 0; i < arraysize(kInterfaceInfo); ++i) {
    CComPtr<IUnknown> factory;
    const InterfaceInfo& info = kInterfaceInfo[i];
    HRESULT hr = ToolbandProxyDllGetClassObject(*info.iid, IID_IUnknown,
        reinterpret_cast<void**>(&factory));

    DWORD cookie = 0;
    if (SUCCEEDED(hr)) {
      hr = ::CoRegisterClassObject(*info.iid, factory, CLSCTX_INPROC_SERVER,
          REGCLS_MULTIPLEUSE, &cookie);
    }
    if (SUCCEEDED(hr)) {
      // Proxy/stubs have their own IID as class id.
      hr = ::CoRegisterPSClsid(*info.iid, *info.iid);
      if (SUCCEEDED(hr) && cookies != NULL) {
        cookies->push_back(cookie);
      }
    }

#ifndef NDEBUG
    // If there's a corresponding Async interface, check whether
    // it's registered. This is a debugging aid only.
    if (info.async_iid != NULL)
      CheckAsyncIidRegistered(*info.iid, *info.async_iid);
#endif  // NDEBUG

    if (FAILED(hr)) {
      succeeded = false;
      LOG(ERROR) << "Failed to register proxy " << com::LogHr(hr);
    }
  }

  VLOG(1) << "Registered toolband proxy/stubs in thread "
      << ::GetCurrentThreadId();

  return succeeded;
}

void UnregisterProxyStubs(const std::vector<DWORD>& cookies) {
  for (size_t i = 0; i < cookies.size(); ++i) {
    HRESULT hr = ::CoRevokeClassObject(cookies[i]);
    if (FAILED(hr)) {
      LOG(ERROR) << "Failed to revoke class object " << com::LogHr(hr);
    }
  }
}

bool RegisterAsyncProxies(bool reg) {
  for (size_t i = 0; i < arraysize(kInterfaceInfo); ++i) {
    // Register the iid->async iid mapping for async interfaces.
    if (kInterfaceInfo[i].async_iid != NULL) {
      const InterfaceInfo& info = kInterfaceInfo[i];
      std::wstring iid_str;
      bool success = com::GuidToString(*info.iid, &iid_str);
      DCHECK(success) << "Failed to stringify GUID";
      std::wstring async_iid_str;
      success = com::GuidToString(*info.async_iid, &async_iid_str);
      DCHECK(success) << "Failed to stringify GUID";

      _ATL_REGMAP_ENTRY entries[] = {
        { L"IID", iid_str.c_str() },
        { L"ASYNC_IID", async_iid_str.c_str() },
        { L"NAME", info.name },
        { NULL, NULL },
      };

      HRESULT hr = _pAtlModule->UpdateRegistryFromResource(
           MAKEINTRESOURCE(IDR_TOOLBAND_PROXY), reg, entries);
      if (FAILED(hr)) {
        LOG(ERROR) << "Failed to register async interface for " <<
            info.name << com::LogHr(hr);
        return false;
      }
    }
  }

  return true;
}
<commit_msg>Commit for siggi, original http://codereview.chromium.org/5385004/<commit_after>// Copyright (c) 2010 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.
#include "ceee/ie/plugin/toolband/toolband_proxy.h"

#include <atlbase.h>
#include "base/logging.h"
#include "base/stringprintf.h"
#include "base/win/registry.h"
#include "ceee/common/com_utils.h"
#include "ceee/ie/plugin/toolband/resource.h"

#include "toolband.h"  // NOLINT

extern "C" {
// Declare the entrypoint function(s) generated by MIDL for our proxy/stubs.
HRESULT STDAPICALLTYPE ToolbandProxyDllGetClassObject(REFCLSID clsid,
                                                      REFIID iid,
                                                      void** ppv);
}  // extern "C"

namespace {

struct InterfaceInfo {
  const wchar_t* name;
  const IID* iid;
  const IID* async_iid;
};

#define DECLARE_SYNC_INTERFACE(itf) \
  { L#itf, &IID_##itf, NULL },
#define DECLARE_ASYNC_INTERFACE(itf) \
  { L#itf, &IID_##itf, &IID_Async##itf }, \
  DECLARE_SYNC_INTERFACE(Async##itf)

// If you add new executor interfaces to toolband.idl, make sure to add
// their IIDs here, or you will not be able to marshal them.
const InterfaceInfo kInterfaceInfo[] = {
  DECLARE_SYNC_INTERFACE(ICeeeWindowExecutor)
  DECLARE_ASYNC_INTERFACE(ICeeeTabExecutor)
  DECLARE_SYNC_INTERFACE(ICeeeCookieExecutor)
  DECLARE_SYNC_INTERFACE(ICeeeInfobarExecutor)
};

#ifndef NDEBUG
void CheckAsyncIidRegistered(const IID& iid, const IID& async_iid) {
  std::wstring iid_str;
  bool success = com::GuidToString(iid, &iid_str);
  DCHECK(success);
  std::wstring key_name = base::StringPrintf(
      L"Interface\\%ls\\AsynchronousInterface", iid_str.c_str());

  base::win::RegKey key;
  if (key.Open(HKEY_CLASSES_ROOT, key_name.c_str(), KEY_READ)) {
    // It's registered, the rest of this block is debug checking that
    // the correct IID is indeed registered for the async interface.
    std::wstring async_iid_str;
    DCHECK(key.ReadValue(NULL, &async_iid_str));
    IID read_async_iid;
    DCHECK(SUCCEEDED(::IIDFromString(async_iid_str.c_str(), &read_async_iid)));
    DCHECK(read_async_iid == async_iid);
  } else {
    LOG(WARNING) << "Sync->Async IID not registered. Key=" << key_name;
  }
}
#endif  // NDEBUG

}  // namespace

bool RegisterProxyStubs(std::vector<DWORD>* cookies) {
  bool succeeded = true;

  for (size_t i = 0; i < arraysize(kInterfaceInfo); ++i) {
    CComPtr<IUnknown> factory;
    const InterfaceInfo& info = kInterfaceInfo[i];
    HRESULT hr = ToolbandProxyDllGetClassObject(*info.iid, IID_IUnknown,
        reinterpret_cast<void**>(&factory));

    DWORD cookie = 0;
    if (SUCCEEDED(hr)) {
      hr = ::CoRegisterClassObject(*info.iid, factory, CLSCTX_INPROC_SERVER,
          REGCLS_MULTIPLEUSE, &cookie);
    }
    if (SUCCEEDED(hr)) {
      // Proxy/stubs have their own IID as class id.
      hr = ::CoRegisterPSClsid(*info.iid, *info.iid);
      if (SUCCEEDED(hr) && cookies != NULL) {
        cookies->push_back(cookie);
      }
    }

#ifndef NDEBUG
    // If there's a corresponding Async interface, check whether
    // it's registered. This is a debugging aid only.
    if (info.async_iid != NULL)
      CheckAsyncIidRegistered(*info.iid, *info.async_iid);
#endif  // NDEBUG

    if (FAILED(hr)) {
      succeeded = false;
      LOG(ERROR) << "Failed to register proxy " << com::LogHr(hr);
    }
  }

  VLOG(1) << "Registered toolband proxy/stubs in thread "
      << ::GetCurrentThreadId();

  return succeeded;
}

void UnregisterProxyStubs(const std::vector<DWORD>& cookies) {
  for (size_t i = 0; i < cookies.size(); ++i) {
    HRESULT hr = ::CoRevokeClassObject(cookies[i]);
    if (FAILED(hr)) {
      LOG(ERROR) << "Failed to revoke class object " << com::LogHr(hr);
    }
  }
}

bool RegisterAsyncProxies(bool reg) {
  for (size_t i = 0; i < arraysize(kInterfaceInfo); ++i) {
    // Register the iid->async iid mapping for async interfaces.
    if (kInterfaceInfo[i].async_iid != NULL) {
      const InterfaceInfo& info = kInterfaceInfo[i];
      std::wstring iid_str;
      bool success = com::GuidToString(*info.iid, &iid_str);
      DCHECK(success) << "Failed to stringify GUID";
      std::wstring async_iid_str;
      success = com::GuidToString(*info.async_iid, &async_iid_str);
      DCHECK(success) << "Failed to stringify GUID";

      _ATL_REGMAP_ENTRY entries[] = {
        { L"IID", iid_str.c_str() },
        { L"ASYNC_IID", async_iid_str.c_str() },
        { L"NAME", info.name },
        { NULL, NULL },
      };

      HRESULT hr = _pAtlModule->UpdateRegistryFromResource(
           MAKEINTRESOURCE(IDR_TOOLBAND_PROXY), reg, entries);
      if (FAILED(hr)) {
        LOG(ERROR) << "Failed to register async interface for " <<
            info.name << com::LogHr(hr);
        return false;
      }
    }
  }

  return true;
}
<|endoftext|>


<commit_before>#include "wiVersion.h"

#include <string>

namespace wi::version
{
	// main engine core
	const int major = 0;
	// minor features, major updates, breaking compatibility changes
	const int minor = 71;
	// minor bug fixes, alterations, refactors, updates
	const int revision = 77;

	const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);

	int GetMajor()
	{
		return major;
	}
	int GetMinor()
	{
		return minor;
	}
	int GetRevision()
	{
		return revision;
	}
	const char* GetVersionString()
	{
		return version_string.c_str();
	}

	const char* GetCreditsString()
	{
		static const char* credits = R"(
Credits
-----------
Created by Turánszki János | https://github.com/turanszkij

Contributors
------------------
- Silas Oler | https://github.com/Kliaxe
	- Stochastic Screen Space Reflections
	- Realistic Sky
	- Volumetric clouds
	- Exponential height fog
- Matteo De Carlo | https://github.com/portaloffreedom
	- Linux core systems
	- Cmake
- XThemeCore | https://github.com/XthemeCore
	- Morph targets
- Amer Koleci https://github.com/amerkoleci
	- Windows Cmake
	- Graphics API improvements
	- Dear ImGui integration
	- Refactors, fixes
- James Webb | https://github.com/jdswebb
	- Graphics API improvements
	- Fixes
- Ben Vinson | https://github.com/BenV
	- Fixes
- Alexander Weinrauch | https://github.com/AlexAUT
	- Fixes
- Eric Fedosejevs | https://github.com/efedo
	- Fixes
- Johan Aires Rastén | https://github.com/JohanAR
	- Fixes
- Megumumpkin | https://github.com/megumumpkin
	- Linux audio implementation
	- Linux controller implementation
	- Linux network implementation
	- ComponentLibrary implementation
	- Lua property bindings support, improvements
	- Fixes
- Maeve Garside | https://github.com/MolassesLover
	- Linux package files
	- Visual Studio Code support improvement
	- Linux template
- Igor Alexey | https://github.com/sororfortuna
	- QOI image loader integration
- Eddie Ataberk | https://github.com/eddieataberk
	- Physics improvements
- Preben Eriksen | https://github.com/plemsoft
	- Fixes
	- Dear ImGui docking sample.
- matpx | https://github.com/matpx
	- Fixes
- Dennis Brakhane | https://github.com/brakhane
	- Added Liberation Sans default font

Patreon supporters
---------------------------
- Nemerle
- James Webb
- Quifeng Jin
- TheGameCreators
- Joseph Goldin
- Yuri
- Sergey K
- Yukawa Kanta
- Dragon Josh
- John
- LurkingNinja
- Bernardo Del Castillo
- Invictus
- Scott Hunt
- Yazan Altaki
- Tuan NV
- Robert MacGregor
- cybernescence
- Alexander Dahlin
- blueapples
- Delhills
- NI NI
- Sherief
- ktopoet
		)";

		return credits;
	}

}
<commit_msg>updated credits<commit_after>#include "wiVersion.h"

#include <string>

namespace wi::version
{
	// main engine core
	const int major = 0;
	// minor features, major updates, breaking compatibility changes
	const int minor = 71;
	// minor bug fixes, alterations, refactors, updates
	const int revision = 77;

	const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);

	int GetMajor()
	{
		return major;
	}
	int GetMinor()
	{
		return minor;
	}
	int GetRevision()
	{
		return revision;
	}
	const char* GetVersionString()
	{
		return version_string.c_str();
	}

	const char* GetCreditsString()
	{
		static const char* credits = R"(
Credits
-----------
Created by Turánszki János | https://github.com/turanszkij

Contributors
------------------
- Silas Oler | https://github.com/Kliaxe
	- Stochastic Screen Space Reflections
	- Realistic Sky
	- Volumetric clouds
	- Exponential height fog
- Matteo De Carlo | https://github.com/portaloffreedom
	- Linux core systems
	- Cmake
- XThemeCore | https://github.com/XthemeCore
	- Morph targets
- Amer Koleci https://github.com/amerkoleci
	- Windows Cmake
	- Graphics API improvements
	- Dear ImGui integration
	- Refactors, fixes
- James Webb | https://github.com/jdswebb
	- Graphics API improvements
	- Fixes
- Ben Vinson | https://github.com/BenV
	- Fixes
- Alexander Weinrauch | https://github.com/AlexAUT
	- Fixes
- Eric Fedosejevs | https://github.com/efedo
	- Fixes
- Johan Aires Rastén | https://github.com/JohanAR
	- Fixes
- Megumumpkin | https://github.com/megumumpkin
	- Linux audio implementation
	- Linux controller implementation
	- Linux network implementation
	- ComponentLibrary implementation
	- Lua property bindings support, improvements
	- Fixes
- Maeve Garside | https://github.com/MolassesLover
	- Linux package files
	- Visual Studio Code support improvement
	- Linux template
- Igor Alexey | https://github.com/sororfortuna
	- QOI image loader integration
- Eddie Ataberk | https://github.com/eddieataberk
	- Physics improvements
- Preben Eriksen | https://github.com/plemsoft
	- Fixes
	- Dear ImGui docking sample.
- matpx | https://github.com/matpx
	- Fixes
- Dennis Brakhane | https://github.com/brakhane
	- Added Liberation Sans default font
- Cop46 | https://github.com/Cop46
	- Brightness, Contrast, Saturation post process

Patreon supporters
---------------------------
- Nemerle
- James Webb
- Quifeng Jin
- TheGameCreators
- Joseph Goldin
- Yuri
- Sergey K
- Yukawa Kanta
- Dragon Josh
- John
- LurkingNinja
- Bernardo Del Castillo
- Invictus
- Scott Hunt
- Yazan Altaki
- Tuan NV
- Robert MacGregor
- cybernescence
- Alexander Dahlin
- blueapples
- Delhills
- NI NI
- Sherief
- ktopoet
- Justin Macklin
- Cédric Fabre
- TogetherTeam
- Bartosz Boczula
		)";

		return credits;
	}

}
<|endoftext|>


<commit_before>#include "qjulia.h"
#include "qjulia.cpp"

#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <process.h>

#define k_max_thread_count 16

struct thread_context_t
{
    HANDLE h;
    uint32_t id;
    HANDLE done_event;
    application_context_t *app;
};

struct system_context_t
{
    HWND hwnd;
    HDC hdc, mdc;
    HBITMAP hbm;

    HANDLE quit_event;
    HANDLE render_semaphore;
    uint32_t thread_count;
    thread_context_t thread[k_max_thread_count];
    volatile long tile_index;
};

static uint32_t WINAPI
win_render_thread(void *context)
{
    thread_context_t *thread = (thread_context_t *)context;
    assert(thread && thread->app && thread->app->sys);

    system_context_t *sys = thread->app->sys;

    HANDLE wait[2] = { sys->quit_event, sys->render_semaphore };

    for (;;) {
        DWORD r = WaitForMultipleObjects(2, wait, FALSE, INFINITE);
        if (r == WAIT_OBJECT_0) break;

        for (;;) {
            uint32_t idx = (uint32_t)_InterlockedExchangeAdd(&sys->tile_index, 1);
            if (idx >= k_tile_count) break;
            render_tile(thread->app, idx);
        }

        SetEvent(thread->done_event);
    }

    return 0;
}

static LRESULT CALLBACK
win_message_handler(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch (msg) {
        case WM_DESTROY:
        case WM_KEYDOWN:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(win, msg, wparam, lparam);
}

static double
sys_get_time()
{
    static LARGE_INTEGER freq = {};
    static LARGE_INTEGER counter0 = {};

    if (freq.QuadPart == 0) {
        QueryPerformanceFrequency(&freq);
        QueryPerformanceCounter(&counter0);
    }
    LARGE_INTEGER counter;
    QueryPerformanceCounter(&counter);
    return (counter.QuadPart - counter0.QuadPart) / (double)freq.QuadPart;
}

static void
sys_display_text(system_context_t *sys, const char *text)
{
    assert(sys && text);
    SetWindowText(sys->hwnd, text);
}

static bool
win_init(application_context_t *app)
{
    assert(app && app->sys);
    system_context_t *sys = app->sys;

    WNDCLASS winclass = {};
    winclass.lpfnWndProc = win_message_handler;
    winclass.hInstance = GetModuleHandle(NULL);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winclass.lpszClassName = k_app_name;
    if (!RegisterClass(&winclass)) return false;

    RECT rect = { 0, 0, k_app_resx, k_app_resy };
    if (!AdjustWindowRect(&rect, WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
                          FALSE))
        return false;

    sys->hwnd = CreateWindow(k_app_name, k_app_name,
                             WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX |
                             WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
                             rect.right - rect.left, rect.bottom - rect.top,
                             NULL, NULL, NULL, 0);
    if (!sys->hwnd) return false;
    if (!(sys->hdc = GetDC(sys->hwnd))) return false;

    BITMAPINFO bi = {};
    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = 32;
    bi.bmiHeader.biCompression = BI_RGB;
    bi.bmiHeader.biWidth = k_app_resx;
    bi.bmiHeader.biHeight = -k_app_resy;
    bi.bmiHeader.biSizeImage = k_app_resx * k_app_resy;
    sys->mdc = CreateCompatibleDC(sys->hdc);
    sys->hbm = CreateDIBSection(sys->hdc, &bi, DIB_RGB_COLORS, (void **)&app->displayptr,
                                NULL, 0);

    if (!SelectObject(sys->mdc, sys->hbm)) return false;

    sys->quit_event = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
    if (!sys->quit_event) return false;

    sys->render_semaphore = CreateSemaphore(NULL, 0, sys->thread_count, NULL);
    if (!sys->render_semaphore) return false;

    for (uint32_t i = 0; i < sys->thread_count; ++i) {
        sys->thread[i].app = app;
        sys->thread[i].h = NULL;
        sys->thread[i].id = i;
        sys->thread[i].done_event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
        if (!sys->thread[i].done_event) return false;
    }
    for (uint32_t i = 0; i < sys->thread_count; ++i) {
        sys->thread[i].h = (HANDLE)_beginthreadex(NULL, 0, win_render_thread,
                                                  &sys->thread[i], 0, NULL);
        if (!sys->thread[i].h) return false;
    }

    return true;
}

static void
win_deinit(system_context_t *sys)
{
    assert(sys);
    if (sys->hdc) {
        ReleaseDC(sys->hwnd, sys->hdc);
        sys->hdc = NULL;
    }
}

static void
win_update(system_context_t *sys)
{
    assert(sys);

    _InterlockedExchange(&sys->tile_index, 0);

    ReleaseSemaphore(sys->render_semaphore, sys->thread_count, NULL);

    HANDLE done[k_max_thread_count];
    for (uint32_t i = 0; i < sys->thread_count; ++i) {
        done[i] = sys->thread[i].done_event;
    }
    WaitForMultipleObjects(sys->thread_count, done, TRUE, INFINITE);

    BitBlt(sys->hdc, 0, 0, k_app_resx, k_app_resy, sys->mdc, 0, 0, SRCCOPY);
}

int
main()
{
    system_context_t sys = {};
    application_context_t app = {};
    app.sys = &sys;

    SYSTEM_INFO si;
    GetSystemInfo(&si);
    sys.thread_count = (uint32_t)si.dwNumberOfProcessors;

    if (!win_init(&app)) {
        win_deinit(&sys);
        return 1;
    }

    MSG msg = { 0 };
    for (;;) {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
            DispatchMessage(&msg);
            if (msg.message == WM_QUIT) break;
        } else {
            update(&app);
            win_update(&sys);
        }
    }

    win_deinit(&sys);
    return 0;
}
<commit_msg>Update<commit_after>#include "qjulia.h"
#include "qjulia.cpp"

#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <process.h>

#define k_max_thread_count 16

struct thread_context_t
{
    HANDLE h;
    uint32_t id;
    HANDLE start_event, done_event;
    application_context_t *app;
};

struct system_context_t
{
    HWND hwnd;
    HDC hdc, mdc;
    HBITMAP hbm;

    HANDLE quit_event;
    uint32_t thread_count;
    thread_context_t thread[k_max_thread_count];
    volatile long tile_index;
};

static uint32_t WINAPI
win_render_thread(void *context)
{
    thread_context_t *thread = (thread_context_t *)context;
    assert(thread && thread->app && thread->app->sys);

    system_context_t *sys = thread->app->sys;

    HANDLE wait[2] = { sys->quit_event, thread->start_event };

    for (;;) {
        DWORD r = WaitForMultipleObjects(2, wait, FALSE, INFINITE);
        if (r == WAIT_OBJECT_0) break;

        for (;;) {
            uint32_t idx = (uint32_t)_InterlockedExchangeAdd(&sys->tile_index, 1);
            if (idx >= k_tile_count) break;
            render_tile(thread->app, idx);
        }

        SetEvent(thread->done_event);
    }

    return 0;
}

static LRESULT CALLBACK
win_message_handler(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch (msg) {
        case WM_DESTROY:
        case WM_KEYDOWN:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(win, msg, wparam, lparam);
}

static double
sys_get_time()
{
    static LARGE_INTEGER freq = {};
    static LARGE_INTEGER counter0 = {};

    if (freq.QuadPart == 0) {
        QueryPerformanceFrequency(&freq);
        QueryPerformanceCounter(&counter0);
    }
    LARGE_INTEGER counter;
    QueryPerformanceCounter(&counter);
    return (counter.QuadPart - counter0.QuadPart) / (double)freq.QuadPart;
}

static void
sys_display_text(system_context_t *sys, const char *text)
{
    assert(sys && text);
    SetWindowText(sys->hwnd, text);
}

static bool
win_init(application_context_t *app)
{
    assert(app && app->sys);
    system_context_t *sys = app->sys;

    WNDCLASS winclass = {};
    winclass.lpfnWndProc = win_message_handler;
    winclass.hInstance = GetModuleHandle(NULL);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winclass.lpszClassName = k_app_name;
    if (!RegisterClass(&winclass)) return false;

    RECT rect = { 0, 0, k_app_resx, k_app_resy };
    if (!AdjustWindowRect(&rect, WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
                          FALSE))
        return false;

    sys->hwnd = CreateWindow(k_app_name, k_app_name,
                             WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX |
                             WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
                             rect.right - rect.left, rect.bottom - rect.top,
                             NULL, NULL, NULL, 0);
    if (!sys->hwnd) return false;
    if (!(sys->hdc = GetDC(sys->hwnd))) return false;

    BITMAPINFO bi = {};
    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = 32;
    bi.bmiHeader.biCompression = BI_RGB;
    bi.bmiHeader.biWidth = k_app_resx;
    bi.bmiHeader.biHeight = -k_app_resy;
    bi.bmiHeader.biSizeImage = k_app_resx * k_app_resy;
    sys->mdc = CreateCompatibleDC(sys->hdc);
    sys->hbm = CreateDIBSection(sys->hdc, &bi, DIB_RGB_COLORS, (void **)&app->displayptr,
                                NULL, 0);

    if (!SelectObject(sys->mdc, sys->hbm)) return false;

    sys->quit_event = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
    if (!sys->quit_event) return false;

    for (uint32_t i = 0; i < sys->thread_count; ++i) {
        sys->thread[i].app = app;
        sys->thread[i].h = NULL;
        sys->thread[i].id = i;
        sys->thread[i].start_event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
        sys->thread[i].done_event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
        if (!sys->thread[i].done_event || !sys->thread[i].start_event) return false;
    }
    for (uint32_t i = 0; i < sys->thread_count; ++i) {
        sys->thread[i].h = (HANDLE)_beginthreadex(NULL, 0, win_render_thread,
                                                  &sys->thread[i], 0, NULL);
        if (!sys->thread[i].h) return false;
    }

    return true;
}

static void
win_deinit(system_context_t *sys)
{
    assert(sys);

    // terminate all worker threads
    SetEvent(sys->quit_event);
    HANDLE done[k_max_thread_count];
    for (uint32_t i = 0; i < sys->thread_count; ++i) done[i] = sys->thread[i].h;
    WaitForMultipleObjects(sys->thread_count, done, TRUE, INFINITE);
    for (uint32_t i = 0; i < sys->thread_count; ++i) CloseHandle(sys->thread[i].h);

    if (sys->hdc) {
        ReleaseDC(sys->hwnd, sys->hdc);
        sys->hdc = NULL;
    }
}

static void
win_update(system_context_t *sys)
{
    assert(sys);

    _InterlockedExchange(&sys->tile_index, 0);

    HANDLE done[k_max_thread_count];
    for (uint32_t i = 0; i < sys->thread_count; ++i) {
        done[i] = sys->thread[i].done_event;
        SetEvent(sys->thread[i].start_event);
    }
    WaitForMultipleObjects(sys->thread_count, done, TRUE, INFINITE);

    BitBlt(sys->hdc, 0, 0, k_app_resx, k_app_resy, sys->mdc, 0, 0, SRCCOPY);
}

int
main()
{
    system_context_t sys = {};
    application_context_t app = {};
    app.sys = &sys;

    SYSTEM_INFO si;
    GetSystemInfo(&si);
    sys.thread_count = (uint32_t)si.dwNumberOfProcessors;

    if (!win_init(&app)) {
        win_deinit(&sys);
        return 1;
    }

    MSG msg = { 0 };
    for (;;) {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
            DispatchMessage(&msg);
            if (msg.message == WM_QUIT) break;
        } else {
            update(&app);
            win_update(&sys);
        }
    }

    win_deinit(&sys);
    return 0;
}
<|endoftext|>


<commit_before>//=============================================================================
//
//	Copyright (C)1999 by Eric Sunshine <sunshine@sunshineco.com>
//
// The contents of this file are copyrighted by Eric Sunshine.  This work 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.  You may distribute this file provided that this
// copyright notice is retained.  Send comments to <sunshine@sunshineco.com>.
//
//=============================================================================
//-----------------------------------------------------------------------------
// NeXTSystemDriver.cpp
//
//	NeXT-specific hardware & operating/system drivers for CrystalSpace.
//
//-----------------------------------------------------------------------------
#include "NeXTSystemDriver.h"
#include "NeXTSystemProxy.h"
#include "version.h"

//-----------------------------------------------------------------------------
// COM interface to NeXT-specific csSystemDriver.
//-----------------------------------------------------------------------------
BEGIN_INTERFACE_TABLE(SysSystemDriver)
    IMPLEMENTS_COMPOSITE_INTERFACE(System)
    IMPLEMENTS_COMPOSITE_INTERFACE(NeXTSystemDriver)
END_INTERFACE_TABLE()

IMPLEMENT_UNKNOWN_NODELETE(SysSystemDriver)
IMPLEMENT_COMPOSITE_UNKNOWN_AS_EMBEDDED(SysSystemDriver, NeXTSystemDriver)

//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
SysSystemDriver::SysSystemDriver() : csSystemDriver(), proxy(0)
    {
    printf("Crystal Space for " OS_NEXT_DESCRIPTION" " VERSION "\nPorted to "
	OS_NEXT_DESCRIPTION " by Eric Sunshine <sunshine@sunshineco.com>\n\n");
    }

//-----------------------------------------------------------------------------
// Destructor
//-----------------------------------------------------------------------------
SysSystemDriver::~SysSystemDriver()
    {
    if (proxy != 0)
	delete proxy;
    }

//-----------------------------------------------------------------------------
// Initialize -- Create the COM --> Objective-C proxy.
//-----------------------------------------------------------------------------
bool SysSystemDriver::Initialize( int argc, char* argv[], IConfig* pconfig )
    {
    proxy = new NeXTSystemProxy( this );
    return superclass::Initialize( argc, argv, pconfig );
    }

//-----------------------------------------------------------------------------
// Loop -- Start the Application's run-loop; return at termination.
//-----------------------------------------------------------------------------
void SysSystemDriver::Loop()
    {
    proxy->start_loop(); // Returns when user requests shutdown.
    }
<commit_msg>Small whitespace fix.<commit_after>//=============================================================================
//
//	Copyright (C)1999 by Eric Sunshine <sunshine@sunshineco.com>
//
// The contents of this file are copyrighted by Eric Sunshine.  This work 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.  You may distribute this file provided that this
// copyright notice is retained.  Send comments to <sunshine@sunshineco.com>.
//
//=============================================================================
//-----------------------------------------------------------------------------
// NeXTSystemDriver.cpp
//
//	NeXT-specific hardware & operating/system drivers for CrystalSpace.
//
//-----------------------------------------------------------------------------
#include "NeXTSystemDriver.h"
#include "NeXTSystemProxy.h"
#include "version.h"

//-----------------------------------------------------------------------------
// COM interface to NeXT-specific csSystemDriver.
//-----------------------------------------------------------------------------
BEGIN_INTERFACE_TABLE(SysSystemDriver)
    IMPLEMENTS_COMPOSITE_INTERFACE(System)
    IMPLEMENTS_COMPOSITE_INTERFACE(NeXTSystemDriver)
END_INTERFACE_TABLE()

IMPLEMENT_UNKNOWN_NODELETE(SysSystemDriver)
IMPLEMENT_COMPOSITE_UNKNOWN_AS_EMBEDDED(SysSystemDriver, NeXTSystemDriver)

//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
SysSystemDriver::SysSystemDriver() : csSystemDriver(), proxy(0)
    {
    printf("Crystal Space for " OS_NEXT_DESCRIPTION " " VERSION "\nPorted to "
	OS_NEXT_DESCRIPTION " by Eric Sunshine <sunshine@sunshineco.com>\n\n");
    }

//-----------------------------------------------------------------------------
// Destructor
//-----------------------------------------------------------------------------
SysSystemDriver::~SysSystemDriver()
    {
    if (proxy != 0)
	delete proxy;
    }

//-----------------------------------------------------------------------------
// Initialize -- Create the COM --> Objective-C proxy.
//-----------------------------------------------------------------------------
bool SysSystemDriver::Initialize( int argc, char* argv[], IConfig* pconfig )
    {
    proxy = new NeXTSystemProxy( this );
    return superclass::Initialize( argc, argv, pconfig );
    }

//-----------------------------------------------------------------------------
// Loop -- Start the Application's run-loop; return at termination.
//-----------------------------------------------------------------------------
void SysSystemDriver::Loop()
    {
    proxy->start_loop(); // Returns when user requests shutdown.
    }
<|endoftext|>


<commit_before>/*  -*-c++-*-
 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
 */

#include <osgAnimation/VertexInfluence>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/RigTransformSoftware>
#include <sstream>

using namespace osgAnimation;

// The idea is to compute a bounding box with a factor x of the first step we compute the bounding box
osg::BoundingBox RigComputeBoundingBoxCallback::computeBound(const osg::Drawable& drawable) const
{
    const osgAnimation::RigGeometry& rig = dynamic_cast<const osgAnimation::RigGeometry&>(drawable);

    // if a valid initial bounding box is set we use it without asking more
    if (rig.getInitialBound().valid())
        return rig.getInitialBound();

    if (_computed)
        return _boundingBox;

    // if the computing of bb is invalid (like no geometry inside)
    // then don't tag the bounding box as computed
    osg::BoundingBox bb = rig.computeBoundingBox();
    if (!bb.valid())
        return bb;

    _boundingBox.expandBy(bb);
    osg::Vec3 center = _boundingBox.center();
    osg::Vec3 vec = (_boundingBox._max-center)*_factor;
    _boundingBox.expandBy(center + vec);
    _boundingBox.expandBy(center - vec);
    _computed = true;
//        OSG_NOTICE << "build the bounding box for RigGeometry " << rig.getName() << " " << _boundingBox._min << " " << _boundingBox._max << std::endl;
    return _boundingBox;
}

RigGeometry::RigGeometry()
{
    _supportsDisplayList = false;
    setUseVertexBufferObjects(true);
    setUpdateCallback(new UpdateRigGeometry);
    setDataVariance(osg::Object::DYNAMIC);
    _needToComputeMatrix = true;
    _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
    // disable the computation of boundingbox for the rig mesh
    setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback());
    _rigTransformImplementation = new osgAnimation::RigTransformSoftware;

}

RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
    osg::Geometry(b,copyop),
    _geometry(b._geometry),
    _rigTransformImplementation(osg::clone(_rigTransformImplementation.get(), copyop)),
    _vertexInfluenceMap(b._vertexInfluenceMap),
    _needToComputeMatrix(b._needToComputeMatrix)
{
    _needToComputeMatrix = true;
    _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
    // disable the computation of boundingbox for the rig mesh

    setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback());
    // we don't copy the RigImplementation yet. because the RigImplementation need to be initialized in a valid graph, with a skeleton ...
    // don't know yet what to do with a clone of a RigGeometry

}

const osg::Matrix& RigGeometry::getMatrixFromSkeletonToGeometry() const { return _matrixFromSkeletonToGeometry; }
const osg::Matrix& RigGeometry::getInvMatrixFromSkeletonToGeometry() const { return _invMatrixFromSkeletonToGeometry;}

void RigGeometry::computeMatrixFromRootSkeleton()
{
    if (!_root.valid())
    {
        OSG_WARN << "Warning " << className() <<"::computeMatrixFromRootSkeleton if you have this message it means you miss to call buildTransformer(Skeleton* root), or your RigGeometry (" << getName() <<") is not attached to a Skeleton subgraph" << std::endl;
        return;
    }
    osg::MatrixList mtxList = getParent(0)->getWorldMatrices(_root.get());
    osg::Matrix notRoot = _root->getMatrix();
    _matrixFromSkeletonToGeometry = mtxList[0] * osg::Matrix::inverse(notRoot);
    _invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry);
    _needToComputeMatrix = false;
}

void RigGeometry::update()
{
    RigTransform& implementation = *_rigTransformImplementation;
    (implementation)(*this);
}

void RigGeometry::copyFrom(osg::Geometry& from)
{
    if (this==&from) return;

    osg::Geometry& target = *this;

    target.setStateSet(from.getStateSet());

    // copy over primitive sets.
    target.getPrimitiveSetList() = from.getPrimitiveSetList();

    if (from.getVertexArray())
    {
        target.setVertexArray(from.getVertexArray());
    }

    if (from.getNormalArray())
    {
        target.setNormalArray(from.getNormalArray());
    }

    if (from.getColorArray())
    {
        target.setColorArray(from.getColorArray());
    }

    if (from.getSecondaryColorArray())
    {
        target.setSecondaryColorArray(from.getSecondaryColorArray());
    }

    if (from.getFogCoordArray())
    {
        target.setFogCoordArray(from.getFogCoordArray());
    }

    for(unsigned int ti=0;ti<from.getNumTexCoordArrays();++ti)
    {
        if (from.getTexCoordArray(ti))
        {
            target.setTexCoordArray(ti,from.getTexCoordArray(ti));
        }
    }

    osg::Geometry::ArrayList& arrayList = from.getVertexAttribArrayList();
    for(unsigned int vi=0;vi< arrayList.size();++vi)
    {
        osg::Array* array = arrayList[vi].get();
        if (array)
        {
            target.setVertexAttribArray(vi,array);
        }
    }
}

<commit_msg>Fixed crash in copy constructor due to copy and paste/typo.<commit_after>/*  -*-c++-*-
 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
 */

#include <osgAnimation/VertexInfluence>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/RigTransformSoftware>
#include <sstream>

using namespace osgAnimation;

// The idea is to compute a bounding box with a factor x of the first step we compute the bounding box
osg::BoundingBox RigComputeBoundingBoxCallback::computeBound(const osg::Drawable& drawable) const
{
    const osgAnimation::RigGeometry& rig = dynamic_cast<const osgAnimation::RigGeometry&>(drawable);

    // if a valid initial bounding box is set we use it without asking more
    if (rig.getInitialBound().valid())
        return rig.getInitialBound();

    if (_computed)
        return _boundingBox;

    // if the computing of bb is invalid (like no geometry inside)
    // then don't tag the bounding box as computed
    osg::BoundingBox bb = rig.computeBoundingBox();
    if (!bb.valid())
        return bb;

    _boundingBox.expandBy(bb);
    osg::Vec3 center = _boundingBox.center();
    osg::Vec3 vec = (_boundingBox._max-center)*_factor;
    _boundingBox.expandBy(center + vec);
    _boundingBox.expandBy(center - vec);
    _computed = true;
//        OSG_NOTICE << "build the bounding box for RigGeometry " << rig.getName() << " " << _boundingBox._min << " " << _boundingBox._max << std::endl;
    return _boundingBox;
}

RigGeometry::RigGeometry()
{
    _supportsDisplayList = false;
    setUseVertexBufferObjects(true);
    setUpdateCallback(new UpdateRigGeometry);
    setDataVariance(osg::Object::DYNAMIC);
    _needToComputeMatrix = true;
    _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
    // disable the computation of boundingbox for the rig mesh
    setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback());
    _rigTransformImplementation = new osgAnimation::RigTransformSoftware;

}

RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
    osg::Geometry(b,copyop),
    _geometry(b._geometry),
    _rigTransformImplementation(osg::clone(b._rigTransformImplementation.get(), copyop)),
    _vertexInfluenceMap(b._vertexInfluenceMap),
    _needToComputeMatrix(b._needToComputeMatrix)
{
    _needToComputeMatrix = true;
    _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
    // disable the computation of boundingbox for the rig mesh

    setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback());
    // we don't copy the RigImplementation yet. because the RigImplementation need to be initialized in a valid graph, with a skeleton ...
    // don't know yet what to do with a clone of a RigGeometry

}

const osg::Matrix& RigGeometry::getMatrixFromSkeletonToGeometry() const { return _matrixFromSkeletonToGeometry; }
const osg::Matrix& RigGeometry::getInvMatrixFromSkeletonToGeometry() const { return _invMatrixFromSkeletonToGeometry;}

void RigGeometry::computeMatrixFromRootSkeleton()
{
    if (!_root.valid())
    {
        OSG_WARN << "Warning " << className() <<"::computeMatrixFromRootSkeleton if you have this message it means you miss to call buildTransformer(Skeleton* root), or your RigGeometry (" << getName() <<") is not attached to a Skeleton subgraph" << std::endl;
        return;
    }
    osg::MatrixList mtxList = getParent(0)->getWorldMatrices(_root.get());
    osg::Matrix notRoot = _root->getMatrix();
    _matrixFromSkeletonToGeometry = mtxList[0] * osg::Matrix::inverse(notRoot);
    _invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry);
    _needToComputeMatrix = false;
}

void RigGeometry::update()
{
    RigTransform& implementation = *_rigTransformImplementation;
    (implementation)(*this);
}

void RigGeometry::copyFrom(osg::Geometry& from)
{
    if (this==&from) return;

    osg::Geometry& target = *this;

    target.setStateSet(from.getStateSet());

    // copy over primitive sets.
    target.getPrimitiveSetList() = from.getPrimitiveSetList();

    if (from.getVertexArray())
    {
        target.setVertexArray(from.getVertexArray());
    }

    if (from.getNormalArray())
    {
        target.setNormalArray(from.getNormalArray());
    }

    if (from.getColorArray())
    {
        target.setColorArray(from.getColorArray());
    }

    if (from.getSecondaryColorArray())
    {
        target.setSecondaryColorArray(from.getSecondaryColorArray());
    }

    if (from.getFogCoordArray())
    {
        target.setFogCoordArray(from.getFogCoordArray());
    }

    for(unsigned int ti=0;ti<from.getNumTexCoordArrays();++ti)
    {
        if (from.getTexCoordArray(ti))
        {
            target.setTexCoordArray(ti,from.getTexCoordArray(ti));
        }
    }

    osg::Geometry::ArrayList& arrayList = from.getVertexAttribArrayList();
    for(unsigned int vi=0;vi< arrayList.size();++vi)
    {
        osg::Array* array = arrayList[vi].get();
        if (array)
        {
            target.setVertexAttribArray(vi,array);
        }
    }
}

<|endoftext|>