<commit_before>/*
    This file is part of KAddressBook.
    Copyright (c) 2002 Mike Pilone <mpilone@slac.com>

    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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 <qcheckbox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qstring.h>
#include <qtoolbutton.h>
#include <qtooltip.h>

#include <kaccelmanager.h>
#include <kconfig.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kiconloader.h>
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>

#include "emaileditwidget.h"

EmailEditWidget::EmailEditWidget( QWidget *parent, const char *name )
  : QWidget( parent, name )
{
  QGridLayout *topLayout = new QGridLayout( this, 2, 2 );
  topLayout->setSpacing( KDialog::spacingHint() );

  QLabel *label = new QLabel( i18n( "Email:" ), this );
  topLayout->addWidget( label, 0, 0 );

  mEmailEdit = new KLineEdit( this );
  connect( mEmailEdit, SIGNAL( textChanged( const QString& ) ),
           SLOT( textChanged( const QString& ) ) );
  connect( mEmailEdit, SIGNAL( textChanged( const QString& ) ),
           SIGNAL( modified() ) );
  label->setBuddy( mEmailEdit );
  topLayout->addWidget( mEmailEdit, 0, 1 );

  QPushButton *editButton = new QPushButton( i18n( "Edit Email Addresses..." ), this);
  connect( editButton, SIGNAL( clicked() ), SLOT( edit() ) );
  topLayout->addMultiCellWidget( editButton, 1, 1, 0, 1 );

  topLayout->activate();
}

EmailEditWidget::~EmailEditWidget()
{
}

void EmailEditWidget::setEmails( const QStringList &list )
{
  mEmailList = list;

  bool blocked = mEmailEdit->signalsBlocked();
  mEmailEdit->blockSignals( true );
  if ( list.count() > 0 )
    mEmailEdit->setText( list[ 0 ] );
  else
    mEmailEdit->setText( "" );
  mEmailEdit->blockSignals( blocked );
}

QStringList EmailEditWidget::emails()
{
  if ( mEmailEdit->text().isEmpty() ) {
    if ( mEmailList.count() > 0 )
      mEmailList.remove( mEmailList.begin() );
  } else {
    if ( mEmailList.count() > 0 )
      mEmailList.remove( mEmailList.begin() );

    mEmailList.prepend( mEmailEdit->text() );
  }

  return mEmailList;
}

void EmailEditWidget::edit()
{
  EmailEditDialog dlg( mEmailList, this );

  if ( dlg.exec() ) {
    if ( dlg.changed() ) {
      mEmailList = dlg.emails();
      mEmailEdit->setText( mEmailList[ 0 ] );
      emit modified();
    }
  }
}

void EmailEditWidget::textChanged( const QString &text )
{
  if ( mEmailList.count() > 0 )
    mEmailList.remove( mEmailList.begin() );

  mEmailList.prepend( text );
}

EmailEditDialog::EmailEditDialog( const QStringList &list, QWidget *parent,
                                  const char *name )
  : KDialogBase( KDialogBase::Plain, i18n( "Edit Email Addresses" ),
                 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
                 parent, name, true )
{
  QWidget *page = plainPage();

  QGridLayout *topLayout = new QGridLayout( page, 4, 3 );

  QLabel *label = new QLabel( i18n( "Email address:" ), page );
  topLayout->addWidget( label, 0, 0 );

  mEmailEdit = new KLineEdit( page );
  label->setBuddy( mEmailEdit );
  topLayout->addWidget( mEmailEdit, 0, 1 );
  connect( mEmailEdit, SIGNAL( returnPressed() ), SLOT( add() ) );
  connect( mEmailEdit, SIGNAL( textChanged( const QString& ) ),
           SLOT( emailChanged() ) );

  mAddButton = new QPushButton( i18n( "Add" ), page );
  mAddButton->setEnabled( false );
  connect( mAddButton, SIGNAL( clicked() ), SLOT( add() ) );
  topLayout->addWidget( mAddButton, 0, 2 );

  mEmailListBox = new QListBox( page );

  // Make sure there is room for the scrollbar
  mEmailListBox->setMinimumHeight( mEmailListBox->sizeHint().height() + 30 );
  connect( mEmailListBox, SIGNAL( highlighted( int ) ),
           SLOT( selectionChanged( int ) ) );
  topLayout->addMultiCellWidget( mEmailListBox, 1, 3, 0, 1 );

  mEditButton = new QPushButton( i18n( "Change" ), page );
  connect( mEditButton, SIGNAL( clicked() ), SLOT( edit() ) );
  topLayout->addWidget( mEditButton, 1, 2 );

  mRemoveButton = new QPushButton( i18n( "Remove" ), page );
  connect( mRemoveButton, SIGNAL( clicked() ), SLOT( remove() ) );
  topLayout->addWidget( mRemoveButton, 2, 2 );

  mStandardButton = new QPushButton( i18n( "Set Standard" ), page );
  connect( mStandardButton, SIGNAL( clicked() ), SLOT( standard() ) );
  topLayout->addWidget( mStandardButton, 3, 2 );

  topLayout->activate();

  QStringList items = list;
  if ( items.remove( "" ) > 0 )
    mChanged = true;
  else
    mChanged = false;
  mEmailListBox->insertStringList( items );

  // set default state
  selectionChanged( -1 );

  KAcceleratorManager::manage( this );
}

EmailEditDialog::~EmailEditDialog()
{
}

QStringList EmailEditDialog::emails() const
{
  QStringList emails;

  for ( uint i = 0; i < mEmailListBox->count(); ++i )
    emails << mEmailListBox->text( i );

  return emails;
}

void EmailEditDialog::add()
{
  mEmailListBox->insertItem( mEmailEdit->text() );

  mEmailEdit->clear();
  mEmailEdit->setFocus();

  mChanged = true;
}

void EmailEditDialog::edit()
{
  mEmailEdit->setText( mEmailListBox->currentText() );
  mEmailEdit->setFocus();
}

void EmailEditDialog::remove()
{
  QString address = mEmailListBox->currentText();

  QString text = i18n( "<qt>Are you sure that you want to remove the email address %1?</qt>" ).arg( address );
  QString caption = i18n( "Confirm Remove" );

  if ( KMessageBox::questionYesNo( this, text, caption ) == KMessageBox::Yes ) {
    mEmailListBox->removeItem( mEmailListBox->currentItem() );
    mChanged = true;
  }
}

bool EmailEditDialog::changed() const
{
  return mChanged;
}

void EmailEditDialog::standard()
{
  QString text = mEmailListBox->currentText();
  mEmailListBox->removeItem( mEmailListBox->currentItem() );
  mEmailListBox->insertItem( text, 0 );
  mEmailListBox->setSelected( 0, true );

  mChanged = true;
}

void EmailEditDialog::selectionChanged( int index )
{
  bool value = ( index >= 0 ); // An item is selected

  mRemoveButton->setEnabled( value );
  mEditButton->setEnabled( value );
  mStandardButton->setEnabled( value );
}

void EmailEditDialog::emailChanged()
{
  mAddButton->setEnabled( !mEmailEdit->text().isEmpty() );
}

#include "emaileditwidget.moc"
<commit_msg>Fixed layout margin/spacing<commit_after>/*
    This file is part of KAddressBook.
    Copyright (c) 2002 Mike Pilone <mpilone@slac.com>

    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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 <qcheckbox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qstring.h>
#include <qtoolbutton.h>
#include <qtooltip.h>

#include <kaccelmanager.h>
#include <kconfig.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kiconloader.h>
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>

#include "emaileditwidget.h"

EmailEditWidget::EmailEditWidget( QWidget *parent, const char *name )
  : QWidget( parent, name )
{
  QGridLayout *topLayout = new QGridLayout( this, 2, 2, KDialog::marginHint(),
                                            KDialog::spacingHint() );

  QLabel *label = new QLabel( i18n( "Email:" ), this );
  topLayout->addWidget( label, 0, 0 );

  mEmailEdit = new KLineEdit( this );
  connect( mEmailEdit, SIGNAL( textChanged( const QString& ) ),
           SLOT( textChanged( const QString& ) ) );
  connect( mEmailEdit, SIGNAL( textChanged( const QString& ) ),
           SIGNAL( modified() ) );
  label->setBuddy( mEmailEdit );
  topLayout->addWidget( mEmailEdit, 0, 1 );

  QPushButton *editButton = new QPushButton( i18n( "Edit Email Addresses..." ), this);
  connect( editButton, SIGNAL( clicked() ), SLOT( edit() ) );
  topLayout->addMultiCellWidget( editButton, 1, 1, 0, 1 );

  topLayout->activate();
}

EmailEditWidget::~EmailEditWidget()
{
}

void EmailEditWidget::setEmails( const QStringList &list )
{
  mEmailList = list;

  bool blocked = mEmailEdit->signalsBlocked();
  mEmailEdit->blockSignals( true );
  if ( list.count() > 0 )
    mEmailEdit->setText( list[ 0 ] );
  else
    mEmailEdit->setText( "" );
  mEmailEdit->blockSignals( blocked );
}

QStringList EmailEditWidget::emails()
{
  if ( mEmailEdit->text().isEmpty() ) {
    if ( mEmailList.count() > 0 )
      mEmailList.remove( mEmailList.begin() );
  } else {
    if ( mEmailList.count() > 0 )
      mEmailList.remove( mEmailList.begin() );

    mEmailList.prepend( mEmailEdit->text() );
  }

  return mEmailList;
}

void EmailEditWidget::edit()
{
  EmailEditDialog dlg( mEmailList, this );

  if ( dlg.exec() ) {
    if ( dlg.changed() ) {
      mEmailList = dlg.emails();
      mEmailEdit->setText( mEmailList[ 0 ] );
      emit modified();
    }
  }
}

void EmailEditWidget::textChanged( const QString &text )
{
  if ( mEmailList.count() > 0 )
    mEmailList.remove( mEmailList.begin() );

  mEmailList.prepend( text );
}

EmailEditDialog::EmailEditDialog( const QStringList &list, QWidget *parent,
                                  const char *name )
  : KDialogBase( KDialogBase::Plain, i18n( "Edit Email Addresses" ),
                 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
                 parent, name, true )
{
  QWidget *page = plainPage();

  QGridLayout *topLayout = new QGridLayout( page, 4, 3, marginHint(),
                                            spacingHint() );

  QLabel *label = new QLabel( i18n( "Email address:" ), page );
  topLayout->addWidget( label, 0, 0 );

  mEmailEdit = new KLineEdit( page );
  label->setBuddy( mEmailEdit );
  topLayout->addWidget( mEmailEdit, 0, 1 );
  connect( mEmailEdit, SIGNAL( returnPressed() ), SLOT( add() ) );
  connect( mEmailEdit, SIGNAL( textChanged( const QString& ) ),
           SLOT( emailChanged() ) );

  mAddButton = new QPushButton( i18n( "Add" ), page );
  mAddButton->setEnabled( false );
  connect( mAddButton, SIGNAL( clicked() ), SLOT( add() ) );
  topLayout->addWidget( mAddButton, 0, 2 );

  mEmailListBox = new QListBox( page );

  // Make sure there is room for the scrollbar
  mEmailListBox->setMinimumHeight( mEmailListBox->sizeHint().height() + 30 );
  connect( mEmailListBox, SIGNAL( highlighted( int ) ),
           SLOT( selectionChanged( int ) ) );
  topLayout->addMultiCellWidget( mEmailListBox, 1, 3, 0, 1 );

  mEditButton = new QPushButton( i18n( "Change" ), page );
  connect( mEditButton, SIGNAL( clicked() ), SLOT( edit() ) );
  topLayout->addWidget( mEditButton, 1, 2 );

  mRemoveButton = new QPushButton( i18n( "Remove" ), page );
  connect( mRemoveButton, SIGNAL( clicked() ), SLOT( remove() ) );
  topLayout->addWidget( mRemoveButton, 2, 2 );

  mStandardButton = new QPushButton( i18n( "Set Standard" ), page );
  connect( mStandardButton, SIGNAL( clicked() ), SLOT( standard() ) );
  topLayout->addWidget( mStandardButton, 3, 2 );

  topLayout->activate();

  QStringList items = list;
  if ( items.remove( "" ) > 0 )
    mChanged = true;
  else
    mChanged = false;
  mEmailListBox->insertStringList( items );

  // set default state
  selectionChanged( -1 );

  KAcceleratorManager::manage( this );
}

EmailEditDialog::~EmailEditDialog()
{
}

QStringList EmailEditDialog::emails() const
{
  QStringList emails;

  for ( uint i = 0; i < mEmailListBox->count(); ++i )
    emails << mEmailListBox->text( i );

  return emails;
}

void EmailEditDialog::add()
{
  mEmailListBox->insertItem( mEmailEdit->text() );

  mEmailEdit->clear();
  mEmailEdit->setFocus();

  mChanged = true;
}

void EmailEditDialog::edit()
{
  mEmailEdit->setText( mEmailListBox->currentText() );
  mEmailEdit->setFocus();
}

void EmailEditDialog::remove()
{
  QString address = mEmailListBox->currentText();

  QString text = i18n( "<qt>Are you sure that you want to remove the email address %1?</qt>" ).arg( address );
  QString caption = i18n( "Confirm Remove" );

  if ( KMessageBox::questionYesNo( this, text, caption ) == KMessageBox::Yes ) {
    mEmailListBox->removeItem( mEmailListBox->currentItem() );
    mChanged = true;
  }
}

bool EmailEditDialog::changed() const
{
  return mChanged;
}

void EmailEditDialog::standard()
{
  QString text = mEmailListBox->currentText();
  mEmailListBox->removeItem( mEmailListBox->currentItem() );
  mEmailListBox->insertItem( text, 0 );
  mEmailListBox->setSelected( 0, true );

  mChanged = true;
}

void EmailEditDialog::selectionChanged( int index )
{
  bool value = ( index >= 0 ); // An item is selected

  mRemoveButton->setEnabled( value );
  mEditButton->setEnabled( value );
  mStandardButton->setEnabled( value );
}

void EmailEditDialog::emailChanged()
{
  mAddButton->setEnabled( !mEmailEdit->text().isEmpty() );
}

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


<commit_before>#include "showcaseview.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QImage>
#include <QBrush>
#include <QLinearGradient>
#include <QSignalMapper>

#include "../../../git/SubZero/src/controller/task/Task.h"
#include "../../../git/SubZero/src/controller/task/TaskCCR.h"
#include "../../../git/SubZero/src/controller/task/TaskHelloWorld.h"
#include "../../../git/SubZero/src/controller/task/TaskHeyTonight.h"

ShowCaseView::ShowCaseView():View()
{
    initializeShowCaseView();

}

void ShowCaseView::initializeShowCaseView()
{
    *frontCameraImage = QImage(":/img/MDA.jpg");

   //Creating an image that holds a gradient of blue

        //Create an image to be painted on
   QImage sub(400,500,QImage::Format_RGB32);

        //Setup the painter to paint/draw on the image
   QPainter subImgPainter;
   subImgPainter.begin(&sub); //Paint on that image

        //Create the gradient
   QLinearGradient blueGradient(0,0,800,600);

        //Set the starting color and end colors
   blueGradient.setColorAt(0.0,QColor(62,58,200));// 0.0 is start position as a qreal
   blueGradient.setColorAt(1.0,QColor(175,80,255)); //1.0 is end position as a qreal

        //Create a brush from the gradient (to paint with)
   QBrush blueGradientBrush(blueGradient);

        //Use the brush
   subImgPainter.fillRect(sub.rect(), blueGradientBrush);
   subImgPainter.end();

    *downCameraImage = sub;

    // Show Case View WIdget Initialization
    movement = new QLabel("Movement");
    leftButton = new QPushButton("Veer Left");
    rightButton = new QPushButton("Veer right");

    specialActions = new QLabel("Special Actions");
    surfaceButton = new QPushButton("Surface");
    fireTorpedoButton = new QPushButton("Fire Torpedo");
    fireGrabberButton = new QPushButton("Fire Grabber");

    systemActions = new QLabel("System Actions");
    menuButton = new QPushButton("Menu");
    exitButton = new QPushButton("Exit");

    // Show Case View layouts

    QVBoxLayout *verticalLayout = new QVBoxLayout;
    QHBoxLayout *mainLayout = new QHBoxLayout;

    //Show Case view Widget Positioning
    //Down want to add rects from view to layout
    //What to do? : set other BoxLayouts and add spacing?

    verticalLayout->addWidget(movement);
    verticalLayout->addWidget(leftButton);
    verticalLayout->addWidget(rightButton);
    verticalLayout->addSpacing(20);//Spacing size of 20 pixels

    verticalLayout->addWidget(specialActions);
    verticalLayout->addWidget(surfaceButton);
    verticalLayout->addWidget(fireTorpedoButton);
    verticalLayout->addWidget(fireGrabberButton);
    verticalLayout->addSpacing(20);//Spacing size of 20 pixels

    verticalLayout->addWidget(systemActions);
    verticalLayout->addWidget(menuButton);
    verticalLayout->addWidget(exitButton);
    verticalLayout->addSpacing(200);//Spacing size of 200 pixels

    mainLayout->addSpacing(800);
    mainLayout->addLayout(verticalLayout);
    this->setLayout(mainLayout);

}

void ShowCaseView::makeQImage(cv::Mat *imgData, QImage *imgHolder)
{
    *imgHolder = QImage(imgData->data, imgData->cols, imgData->rows,QImage::Format_RGB32);

    return;
}

void ShowCaseView::initialize_VC_Connection(Controller *controller)
{
    //Test code to check view and controller connection capabilities
    //Links the 1st 3 buttons of view to controller's first tasks. TaskCCR, TaskHeyTonight, TaskHelloWorld

    //Create holder functions since having trouble with task* - QObject * conversions

    QuickTaskAdder *qta = new QuickTaskAdder();
    qta->initializeQuickTaskAdder(controller);

    connect(leftButton, SIGNAL(clicked()), qta, SLOT(addTaskCCR()));

}

<commit_msg>Delete showcaseview.cpp<commit_after><|endoftext|>


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

// Authors: Jiashun Zhu(zhujiashun@bilibili.com)

#include <vector>
#include <gflags/gflags.h>
#include "brpc/revive_policy.h"
#include "butil/scoped_lock.h"
#include "butil/synchronization/lock.h"
#include "brpc/server_id.h"
#include "brpc/socket.h"
#include "butil/fast_rand.h"
#include "butil/time.h"

namespace brpc {

DEFINE_int64(detect_available_server_interval_ms, 10, "The interval "
        "to detect available server count in DefaultRevivePolicy");

DefaultRevivePolicy::DefaultRevivePolicy(
        int64_t minimum_working_instances, int64_t hold_time_ms)
    : _reviving(false)
    , _minimum_working_instances(minimum_working_instances)
    , _last_usable(0)
    , _last_usable_change_time_ms(0)
    , _hold_time_ms(hold_time_ms)
    , _usable_cache(0)
    , _usable_cache_time_ms(0) { }

void DefaultRevivePolicy::StartReviving() {
    std::unique_lock<butil::Mutex> mu(_mutex);
    _reviving = true;
}

bool DefaultRevivePolicy::StopRevivingIfNecessary() {
    if (!_reviving) {
        return false;
    }
    int64_t now_ms = butil::gettimeofday_ms();
    std::unique_lock<butil::Mutex> mu(_mutex);
    if (_last_usable_change_time_ms != 0 && _last_usable != 0 &&
            (now_ms - _last_usable_change_time_ms > _hold_time_ms)) {
        _reviving = false;
        _last_usable_change_time_ms = 0;
        mu.unlock();
        return false;
    }
    return true;
}

int DefaultRevivePolicy::GetUsableServerCount(
        int64_t now_ms, const std::vector<ServerId>& server_list) {
    if (now_ms - _usable_cache_time_ms < FLAGS_detect_available_server_interval_ms) {
        return _usable_cache;
    }
    int usable = 0;
    size_t n = server_list.size();
    SocketUniquePtr ptr;
    for (size_t i = 0; i < n; ++i) {
        if (Socket::Address(server_list[i].id, &ptr) == 0
            && !ptr->IsLogOff()) {
            usable++;
        }
    }
    {
        std::unique_lock<butil::Mutex> mu(_mutex);
        _usable_cache = usable;
        _usable_cache_time_ms = now_ms;
    }
    return _usable_cache;
}

bool DefaultRevivePolicy::DoReject(const std::vector<ServerId>& server_list) {
    if (!_reviving) {
        return false;
    }
    int64_t now_ms = butil::gettimeofday_ms();
    int usable = GetUsableServerCount(now_ms, server_list);
    {
        std::unique_lock<butil::Mutex> mu(_mutex);
        if (_last_usable != usable) {
            _last_usable = usable;
            _last_usable_change_time_ms = now_ms;
        }
    }
    int rand = butil::fast_rand_less_than(_minimum_working_instances);
    if (rand >= usable) {
        return true;
    }
    return false;
}

} // namespace brpc
<commit_msg>revived_from_all_failed: add double lock<commit_after>// Copyright (c) 2014 Baidu, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Authors: Jiashun Zhu(zhujiashun@bilibili.com)

#include <vector>
#include <gflags/gflags.h>
#include "brpc/revive_policy.h"
#include "butil/scoped_lock.h"
#include "butil/synchronization/lock.h"
#include "brpc/server_id.h"
#include "brpc/socket.h"
#include "butil/fast_rand.h"
#include "butil/time.h"

namespace brpc {

DEFINE_int64(detect_available_server_interval_ms, 10, "The interval "
        "to detect available server count in DefaultRevivePolicy");

DefaultRevivePolicy::DefaultRevivePolicy(
        int64_t minimum_working_instances, int64_t hold_time_ms)
    : _reviving(false)
    , _minimum_working_instances(minimum_working_instances)
    , _last_usable(0)
    , _last_usable_change_time_ms(0)
    , _hold_time_ms(hold_time_ms)
    , _usable_cache(0)
    , _usable_cache_time_ms(0) { }

void DefaultRevivePolicy::StartReviving() {
    std::unique_lock<butil::Mutex> mu(_mutex);
    _reviving = true;
}

bool DefaultRevivePolicy::StopRevivingIfNecessary() {
    if (!_reviving) {
        return false;
    }
    int64_t now_ms = butil::gettimeofday_ms();
    std::unique_lock<butil::Mutex> mu(_mutex);
    if (_last_usable_change_time_ms != 0 && _last_usable != 0 &&
            (now_ms - _last_usable_change_time_ms > _hold_time_ms)) {
        _reviving = false;
        _last_usable_change_time_ms = 0;
        mu.unlock();
        return false;
    }
    mu.unlock();
    return true;
}

int DefaultRevivePolicy::GetUsableServerCount(
        int64_t now_ms, const std::vector<ServerId>& server_list) {
    if (now_ms - _usable_cache_time_ms < FLAGS_detect_available_server_interval_ms) {
        return _usable_cache;
    }
    int usable = 0;
    size_t n = server_list.size();
    SocketUniquePtr ptr;
    for (size_t i = 0; i < n; ++i) {
        if (Socket::Address(server_list[i].id, &ptr) == 0
            && !ptr->IsLogOff()) {
            usable++;
        }
    }
    {
        std::unique_lock<butil::Mutex> mu(_mutex);
        _usable_cache = usable;
        _usable_cache_time_ms = now_ms;
    }
    return _usable_cache;
}

bool DefaultRevivePolicy::DoReject(const std::vector<ServerId>& server_list) {
    if (!_reviving) {
        return false;
    }
    int64_t now_ms = butil::gettimeofday_ms();
    int usable = GetUsableServerCount(now_ms, server_list);
    if (_last_usable != usable) {
        std::unique_lock<butil::Mutex> mu(_mutex);
        if (_last_usable != usable) {
            _last_usable = usable;
            _last_usable_change_time_ms = now_ms;
        }
    }
    int rand = butil::fast_rand_less_than(_minimum_working_instances);
    if (rand >= usable) {
        return true;
    }
    return false;
}

} // namespace brpc
<|endoftext|>


<commit_before><commit_msg>handle incoming invalid piece messages sizes<commit_after><|endoftext|>


<commit_before>// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s

// expected-warning@+1 {{expected quoted string after equals sign}}
///
int test_html1(int);

// expected-warning@+1 {{expected quoted string after equals sign}}
///
int test_html2(int);

// expected-warning@+2 {{expected quoted string after equals sign}}
// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
/// '}}
///
int test_html4(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
///
int test_html5(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
///
int test_html6(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
///
int test_html7(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
/// '}} expected-note@+1 {{HTML tag started here}}
/** Aaa bbb<ccc ddd eee
 * fff ggg.
 */
int test_html9(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
/** Aaa bbb<ccc ddd eee 42%
 * fff ggg.
 */
int test_html10(int);

// expected-warning@+1 {{HTML end tag 'br' is forbidden}}
///

int test_html11(int);

///
Meow

int test_html_nesting1(int);

/// Meow
int test_html_nesting2(int);

///
Aaa

/// Bbb

int test_html_nesting3(int);

///
Aaa

/// Bbb

int test_html_nesting4(int);

// expected-warning@+1 {{HTML end tag does not match any start tag}}
/// Meow
int test_html_nesting5(int);

// expected-warning@+2 {{HTML start tag 'i' closed by 'b'}}
// expected-warning@+1 {{HTML end tag does not match any start tag}}
/// Meow
int test_html_nesting6(int);

// expected-warning@+2 {{HTML start tag 'i' closed by 'b'}}
// expected-warning@+1 {{HTML end tag does not match any start tag}}
/// Meow
int test_html_nesting7(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
int test_block_command1(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief \brief Aaa
int test_block_command2(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief
/// \brief Aaa
int test_block_command3(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief
///
/// \brief Aaa
int test_block_command4(int);

// There is trailing whitespace on one of the following lines, don't remove it!
// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief
///
/// \brief Aaa
int test_block_command5(int);

/// \brief \c Aaa
int test_block_command6(int);

// expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}}
/// \param a Blah blah.
int test_param1;

// expected-warning@+1 {{empty paragraph passed to '\param' command}}
/// \param
/// \param a Blah blah.
int test_param2(int a);

// expected-warning@+1 {{empty paragraph passed to '\param' command}}
/// \param a
int test_param3(int a);

/// \param a Blah blah.
int test_param4(int a);

/// \param [in] a Blah blah.
int test_param5(int a);

/// \param [out] a Blah blah.
int test_param6(int a);

/// \param [in,out] a Blah blah.
int test_param7(int a);

// expected-warning@+1 {{whitespace is not allowed in parameter passing direction}}
/// \param [ in ] a Blah blah.
int test_param8(int a);

// expected-warning@+1 {{whitespace is not allowed in parameter passing direction}}
/// \param [in, out] a Blah blah.
int test_param9(int a);

// expected-warning@+1 {{unrecognized parameter passing direction, valid directions are '[in]', '[out]' and '[in,out]'}}
/// \param [ junk] a Blah blah.
int test_param10(int a);

// expected-warning@+1 {{parameter 'aab' not found in the function declaration}}
/// \param a Blah blah.
int test_param11();

// expected-warning@+1 {{parameter 'A' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}}
/// \param A Blah blah.
int test_param12(int a);

// expected-warning@+1 {{parameter 'aab' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}}
/// \param aab Blah blah.
int test_param13(int aaa, int bbb);

// expected-warning@+1 {{parameter 'aab' not found in the function declaration}}
/// \param aab Blah blah.
int test_param14(int bbb, int ccc);

class C {
  // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}}
  /// \param aaa Blah blah.
  C(int bbb, int ccc);

  // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}}
  /// \param aaa Blah blah.
 int test_param15(int bbb, int ccc);
};

// expected-warning@+3 {{parameter 'a' is already documented}}
// expected-note@+1 {{previous documentation}}
/// \param a Aaa.
/// \param a Aaa.
int test_param16(int a);

// expected-warning@+4 {{parameter 'x2' is already documented}}
// expected-note@+2 {{previous documentation}}
/// \param x1 Aaa.
/// \param x2 Bbb.
/// \param x2 Ccc.
int test_param17(int x1, int x2, int x3);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
int test1; ///< \brief\brief Aaa

// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
int test2, ///< \brief\brief Aaa
    test3; ///< \brief\brief Aaa

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
int test4; ///< \brief
           ///< \brief Aaa

// Check that we attach the comment to the declaration during parsing in the
// following cases.  The test is based on the fact that we don't parse
// documentation comments that are not attached to anything.

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
int test_attach1;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
int test_attach2(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
struct test_attach3 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach4;

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  int test_attach5; ///< \brief\brief Aaa

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach6(int);
};

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
class test_attach7 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach8;

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  int test_attach9; ///< \brief\brief Aaa

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach10(int);
};

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
enum test_attach9 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  test_attach10,

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  test_attach11 ///< \brief\brief Aaa
};

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
struct test_noattach12 *test_attach13;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
typedef struct test_noattach14 *test_attach15;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
typedef struct test_attach16 { int a; } test_attach17;

struct S { int a; };

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
struct S *test_attach18;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
typedef struct S *test_attach19;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
struct test_attach20;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
typedef struct test_attach21 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach22;
} test_attach23;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
namespace test_attach24 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  namespace test_attach25 {
  }
}

// PR13411, reduced.  We used to crash on this.
/**
 * @code Aaa.
 */
void test_nocrash1(int);

<commit_msg>Comment parsing tests: fix test<commit_after>// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s

// expected-warning@+1 {{expected quoted string after equals sign}}
///
int test_html1(int);

// expected-warning@+1 {{expected quoted string after equals sign}}
///
int test_html2(int);

// expected-warning@+2 {{expected quoted string after equals sign}}
// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
/// '}}
///
int test_html4(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
///
int test_html5(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
///
int test_html6(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
///
int test_html7(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
/// '}} expected-note@+1 {{HTML tag started here}}
/** Aaa bbb<ccc ddd eee
 * fff ggg.
 */
int test_html9(int);

// expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
/** Aaa bbb<ccc ddd eee 42%
 * fff ggg.
 */
int test_html10(int);

// expected-warning@+1 {{HTML end tag 'br' is forbidden}}
///

int test_html11(int);

///
Meow

int test_html_nesting1(int);

/// Meow
int test_html_nesting2(int);

///
Aaa

/// Bbb

int test_html_nesting3(int);

///
Aaa

/// Bbb

int test_html_nesting4(int);

// expected-warning@+1 {{HTML end tag does not match any start tag}}
/// Meow
int test_html_nesting5(int);

// expected-warning@+2 {{HTML start tag 'i' closed by 'b'}}
// expected-warning@+1 {{HTML end tag does not match any start tag}}
/// Meow
int test_html_nesting6(int);

// expected-warning@+2 {{HTML start tag 'i' closed by 'b'}}
// expected-warning@+1 {{HTML end tag does not match any start tag}}
/// Meow
int test_html_nesting7(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
int test_block_command1(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief \brief Aaa
int test_block_command2(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief
/// \brief Aaa
int test_block_command3(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief
///
/// \brief Aaa
int test_block_command4(int);

// There is trailing whitespace on one of the following lines, don't remove it!
// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief
///
/// \brief Aaa
int test_block_command5(int);

/// \brief \c Aaa
int test_block_command6(int);

// expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}}
/// \param a Blah blah.
int test_param1;

// expected-warning@+1 {{empty paragraph passed to '\param' command}}
/// \param
/// \param a Blah blah.
int test_param2(int a);

// expected-warning@+1 {{empty paragraph passed to '\param' command}}
/// \param a
int test_param3(int a);

/// \param a Blah blah.
int test_param4(int a);

/// \param [in] a Blah blah.
int test_param5(int a);

/// \param [out] a Blah blah.
int test_param6(int a);

/// \param [in,out] a Blah blah.
int test_param7(int a);

// expected-warning@+1 {{whitespace is not allowed in parameter passing direction}}
/// \param [ in ] a Blah blah.
int test_param8(int a);

// expected-warning@+1 {{whitespace is not allowed in parameter passing direction}}
/// \param [in, out] a Blah blah.
int test_param9(int a);

// expected-warning@+1 {{unrecognized parameter passing direction, valid directions are '[in]', '[out]' and '[in,out]'}}
/// \param [ junk] a Blah blah.
int test_param10(int a);

// expected-warning@+1 {{parameter 'a' not found in the function declaration}}
/// \param a Blah blah.
int test_param11();

// expected-warning@+1 {{parameter 'A' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}}
/// \param A Blah blah.
int test_param12(int a);

// expected-warning@+1 {{parameter 'aab' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}}
/// \param aab Blah blah.
int test_param13(int aaa, int bbb);

// expected-warning@+1 {{parameter 'aab' not found in the function declaration}}
/// \param aab Blah blah.
int test_param14(int bbb, int ccc);

class C {
  // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}}
  /// \param aaa Blah blah.
  C(int bbb, int ccc);

  // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}}
  /// \param aaa Blah blah.
 int test_param15(int bbb, int ccc);
};

// expected-warning@+3 {{parameter 'a' is already documented}}
// expected-note@+1 {{previous documentation}}
/// \param a Aaa.
/// \param a Aaa.
int test_param16(int a);

// expected-warning@+4 {{parameter 'x2' is already documented}}
// expected-note@+2 {{previous documentation}}
/// \param x1 Aaa.
/// \param x2 Bbb.
/// \param x2 Ccc.
int test_param17(int x1, int x2, int x3);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
int test1; ///< \brief\brief Aaa

// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
int test2, ///< \brief\brief Aaa
    test3; ///< \brief\brief Aaa

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
int test4; ///< \brief
           ///< \brief Aaa

// Check that we attach the comment to the declaration during parsing in the
// following cases.  The test is based on the fact that we don't parse
// documentation comments that are not attached to anything.

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
int test_attach1;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
int test_attach2(int);

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
struct test_attach3 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach4;

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  int test_attach5; ///< \brief\brief Aaa

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach6(int);
};

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
class test_attach7 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach8;

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  int test_attach9; ///< \brief\brief Aaa

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach10(int);
};

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
enum test_attach9 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  test_attach10,

  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  test_attach11 ///< \brief\brief Aaa
};

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
struct test_noattach12 *test_attach13;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
typedef struct test_noattach14 *test_attach15;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
typedef struct test_attach16 { int a; } test_attach17;

struct S { int a; };

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
struct S *test_attach18;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
typedef struct S *test_attach19;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
struct test_attach20;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
typedef struct test_attach21 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  int test_attach22;
} test_attach23;

// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
/// \brief\brief Aaa
namespace test_attach24 {
  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
  /// \brief\brief Aaa
  namespace test_attach25 {
  }
}

// PR13411, reduced.  We used to crash on this.
/**
 * @code Aaa.
 */
void test_nocrash1(int);

<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright 2011-2013 The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/software/license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <limits>

#include "UniformDistribution.h"

int main( int argc, char* argv[] )
{
  madai::UniformDistribution distribution;
  if ( distribution.GetMinimum() != 0.0 ) {
    std::cerr << "UniformDistribution minimum should be 0.0" << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetMaximum() != 1.0 ) {
    std::cerr << "UniformDistribution maximum should be 1.0" << std::endl;
    return EXIT_FAILURE;
  }

  double newMinimum = -2.0;
  distribution.SetMinimum( newMinimum );
  if ( distribution.GetMinimum() != newMinimum ) {
    std::cerr << "UniformDistribution::GetMinimum() expected to be " << newMinimum
        << ", was " << distribution.GetMinimum() << std::endl;
    return EXIT_FAILURE;
  }

  double newMaximum = 4.2;
  distribution.SetMaximum( newMaximum );
  if ( distribution.GetMaximum() != newMaximum ) {
    std::cerr << "UniformDistribution::GetMaximum() expected to be " << newMaximum
        << ", was " << distribution.GetMaximum() << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetLogProbabilityDensity( newMinimum - 1.0 ) !=
       -std::numeric_limits< double >::infinity() ) {
    std::cerr << "UniformDistribution::GetLogProbabilityDensity() for value less than "
        << "minimum was not -infinity." << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetLogProbabilityDensity( newMaximum + 1.0 ) !=
       -std::numeric_limits< double >::infinity() ) {
    std::cerr << "UniformDistribution::GetLogProbabilityDensity() for value greater than "
        << "maximum was not -infinity." << std::endl;
    return EXIT_FAILURE;
  }

  double expectedLog = -log( newMaximum - newMinimum );
  double actualLog = distribution.GetLogProbabilityDensity( 0.5 * ( newMinimum + newMaximum ) );
  if ( actualLog != expectedLog ) {
    std::cerr << "UniformDistribution::GetLogProbabilityDensity() for value in range expected "
        << "to return " << expectedLog << ", got " << actualLog << " instead."
        << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetProbabilityDensity( newMinimum - 1.0 ) != 0.0 ) {
    std::cerr << "UniformDistribution::GetProbabilityDensity() for value less than minimum "
        << "should have been 0.0, got << "
        << distribution.GetProbabilityDensity( newMinimum ) << " instead." << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetProbabilityDensity( newMaximum + 1.0 ) != 0.0 ) {
    std::cerr << "UniformDistribution::GetProbabilityDensity() for value greater than maximum "
        << "should have been 0.0, got "
        << distribution.GetProbabilityDensity( newMaximum ) << " instead." << std::endl;
    return EXIT_FAILURE;
  }

  double expectedDensity = 1.0 / ( newMaximum - newMinimum );
  double actualDensity = distribution.GetProbabilityDensity( 0.5 * ( newMinimum + newMaximum ) );
  if ( expectedDensity != actualDensity ) {
    std::cerr << "UniformDistribution::GetProbabilityDensity() for value in range should "
        << "have been " << expectedDensity << ", got " << actualDensity
        << "instead." << std::endl;
    return EXIT_FAILURE;
  }

  double x = 0.32;
  double expectedPercentile = x * ( newMaximum - newMinimum ) + newMinimum;
  double actualPercentile = distribution.GetPercentile( x );
  if ( expectedPercentile != actualPercentile ) {
    std::cerr << "UniformDistribution::GetPercentile() for value " << x << " should have "
        << "been " << expectedPercentile << ", got " << actualPercentile << std::endl;
    return EXIT_FAILURE;
  }

}
<commit_msg>Added equality within a tolerance to some checks<commit_after>/*=========================================================================
 *
 *  Copyright 2011-2013 The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/software/license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <limits>

#include "UniformDistribution.h"

int main( int argc, char* argv[] )
{
  madai::UniformDistribution distribution;
  if ( distribution.GetMinimum() != 0.0 ) {
    std::cerr << "UniformDistribution minimum should be 0.0" << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetMaximum() != 1.0 ) {
    std::cerr << "UniformDistribution maximum should be 1.0" << std::endl;
    return EXIT_FAILURE;
  }

  double newMinimum = -2.0;
  distribution.SetMinimum( newMinimum );
  if ( distribution.GetMinimum() != newMinimum ) {
    std::cerr << "UniformDistribution::GetMinimum() expected to be " << newMinimum
        << ", was " << distribution.GetMinimum() << std::endl;
    return EXIT_FAILURE;
  }

  double newMaximum = 4.2;
  distribution.SetMaximum( newMaximum );
  if ( distribution.GetMaximum() != newMaximum ) {
    std::cerr << "UniformDistribution::GetMaximum() expected to be " << newMaximum
        << ", was " << distribution.GetMaximum() << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetLogProbabilityDensity( newMinimum - 1.0 ) !=
       -std::numeric_limits< double >::infinity() ) {
    std::cerr << "UniformDistribution::GetLogProbabilityDensity() for value less than "
        << "minimum was not -infinity." << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetLogProbabilityDensity( newMaximum + 1.0 ) !=
       -std::numeric_limits< double >::infinity() ) {
    std::cerr << "UniformDistribution::GetLogProbabilityDensity() for value greater than "
        << "maximum was not -infinity." << std::endl;
    return EXIT_FAILURE;
  }

  double expectedLog = -log( newMaximum - newMinimum );
  double actualLog = distribution.GetLogProbabilityDensity( 0.5 * ( newMinimum + newMaximum ) );
  if ( actualLog != expectedLog ) {
    std::cerr << "UniformDistribution::GetLogProbabilityDensity() for value in range expected "
        << "to return " << expectedLog << ", got " << actualLog << " instead."
        << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetProbabilityDensity( newMinimum - 1.0 ) != 0.0 ) {
    std::cerr << "UniformDistribution::GetProbabilityDensity() for value less than minimum "
        << "should have been 0.0, got << "
        << distribution.GetProbabilityDensity( newMinimum ) << " instead." << std::endl;
    return EXIT_FAILURE;
  }

  if ( distribution.GetProbabilityDensity( newMaximum + 1.0 ) != 0.0 ) {
    std::cerr << "UniformDistribution::GetProbabilityDensity() for value greater than maximum "
        << "should have been 0.0, got "
        << distribution.GetProbabilityDensity( newMaximum ) << " instead." << std::endl;
    return EXIT_FAILURE;
  }

  double expectedDensity = 1.0 / ( newMaximum - newMinimum );
  double actualDensity = distribution.GetProbabilityDensity( 0.5 * ( newMinimum + newMaximum ) );
  if ( fabs( expectedDensity - actualDensity ) > 1e-5 ) {
    std::cerr << "UniformDistribution::GetProbabilityDensity() for value in range should "
        << "have been " << expectedDensity << ", got " << actualDensity
        << "instead." << std::endl;
    return EXIT_FAILURE;
  }

  double x = 0.32;
  double expectedPercentile = x * ( newMaximum - newMinimum ) + newMinimum;
  double actualPercentile = distribution.GetPercentile( x );
  if ( fabs( expectedPercentile - actualPercentile ) > 1e-5 ) {
    std::cerr << "UniformDistribution::GetPercentile() for value " << x << " should have "
        << "been " << expectedPercentile << ", got " << actualPercentile << std::endl;
    return EXIT_FAILURE;
  }

}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "OptionsMenu.h"

/* system implementation headers */
#include <vector>
#include <string>

/* common implementation headers */
#include "FontManager.h"
#include "StartupInfo.h"
#include "StateDatabase.h"
#include "TextUtils.h"

/* local implementation headers */
#include "MainMenu.h"
#include "HUDDialogStack.h"
#include "ControlPanel.h"
#include "ServerListCache.h"
#include "HUDuiControl.h"
#include "HUDuiLabel.h"
#include "HUDuiList.h"

/* FIXME - from playing.h */
StartupInfo* getStartupInfo();
extern ControlPanel* controlPanel;

OptionsMenu::OptionsMenu() : guiOptionsMenu(NULL), effectsMenu(NULL),
			     cacheMenu(NULL), saveWorldMenu(NULL),
			     inputMenu(NULL), audioMenu(NULL),
			     displayMenu(NULL)
{
  // cache font face ID
  int fontFace = MainMenu::getFontFace();

  // add controls
  std::vector<HUDuiControl*>& listHUD = getControls();
  HUDuiList* option;
  std::vector<std::string>* options;

  HUDuiLabel* label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setString("Options");
  listHUD.push_back(label);

  inputSetting = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Input Settings");
  listHUD.push_back(label);

  audioSetting = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Audio Settings");
  listHUD.push_back(label);

  displaySetting = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Display Settings");
  listHUD.push_back(label);

  guiOptions = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("GUI Settings");
  listHUD.push_back(label);

  effectsOptions = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Effects Settings");
  listHUD.push_back(label);

  cacheOptions = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Cache Settings");
  listHUD.push_back(label);

  option = new HUDuiList;
  option->setFontFace(fontFace);
  option->setLabel("Save Settings:");
  option->setCallback(callback, (void*)"s");
  options = &option->getList();
  options->push_back(std::string("No"));
  options->push_back(std::string("On Exit"));
  option->update();
  listHUD.push_back(option);

  option = new HUDuiList;
  option->setFontFace(fontFace);
  option->setLabel("Save identity:");
  option->setCallback(callback, (void*)"i");
  options = &option->getList();
  options->push_back(std::string("No"));
  options->push_back(std::string("Username only"));
  options->push_back(std::string("Username and password"));
  option->update();
  listHUD.push_back(option);

  saveWorld = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Save World");
  listHUD.push_back(label);

  initNavigation(listHUD, 1, listHUD.size()-1);
}

OptionsMenu::~OptionsMenu()
{
  delete guiOptionsMenu;
  delete effectsMenu;
  delete cacheMenu;
  delete saveWorldMenu;
  delete inputMenu;
  delete audioMenu;
  delete displayMenu;
}

void OptionsMenu::execute()
{
  HUDuiControl* _focus = HUDui::getFocus();
  if (_focus == guiOptions) {
    if (!guiOptionsMenu) guiOptionsMenu = new GUIOptionsMenu;
    HUDDialogStack::get()->push(guiOptionsMenu);
  } else if (_focus == effectsOptions) {
    if (!effectsMenu) effectsMenu = new EffectsMenu;
    HUDDialogStack::get()->push(effectsMenu);
  } else if (_focus == cacheOptions) {
    if (!cacheMenu) cacheMenu = new CacheMenu;
    HUDDialogStack::get()->push(cacheMenu);
  } else if (_focus == saveWorld) {
    if (!saveWorldMenu) saveWorldMenu = new SaveWorldMenu;
    HUDDialogStack::get()->push(saveWorldMenu);
  } else if (_focus == inputSetting) {
    if (!inputMenu) inputMenu = new InputMenu;
    HUDDialogStack::get()->push(inputMenu);
  } else if (_focus == audioSetting) {
    if (!audioMenu) audioMenu = new AudioMenu;
    HUDDialogStack::get()->push(audioMenu);
  } else if (_focus == displaySetting) {
    if (!displayMenu) displayMenu = new DisplayMenu;
    HUDDialogStack::get()->push(displayMenu);
  }
}

void OptionsMenu::resize(int _width, int _height)
{
  int i;
  HUDDialog::resize(_width, _height);

  // use a big font for title, smaller font for the rest
  const float titleFontSize = (float)_height / 15.0f;
  const float fontSize = (float)_height / 45.0f;
  FontManager &fm = FontManager::instance();

  // reposition title
  std::vector<HUDuiControl*>& listHUD = getControls();
  HUDuiLabel* title = (HUDuiLabel*)listHUD[0];
  title->setFontSize(titleFontSize);
  const float titleWidth = fm.getStrLength(MainMenu::getFontFace(), titleFontSize, title->getString());
  const float titleHeight = fm.getStrHeight(MainMenu::getFontFace(), titleFontSize, " ");
  float x = 0.5f * ((float)_width - titleWidth);
  float y = (float)_height - titleHeight;
  title->setPosition(x, y);

  // reposition options in two columns
  x = 0.5f * (float)_width;
  y -= 0.6f * titleHeight;
  const int count = listHUD.size();
  const float h = fm.getStrHeight(MainMenu::getFontFace(), fontSize, " ");
  for (i = 1; i < count; i++) {
    HUDuiControl *ctl = listHUD[i];
    ctl->setFontSize(fontSize);
    ctl->setPosition(x, y);
    if ((i == 6) || (i == 8)) {
      y -= 1.75f * h;
    } else {
      y -= 1.0f * h;
    }
  }

  // load current settings
  i = 7;

  ((HUDuiList*)listHUD[i++])->setIndex((int)BZDB.eval("saveSettings"));
  ((HUDuiList*)listHUD[i++])->setIndex((int)BZDB.eval("saveIdentity"));
}

void OptionsMenu::callback(HUDuiControl* w, void* data)
{
  HUDuiList* listHUD = (HUDuiList*)w;

  switch (((const char*)data)[0]) {
    case 's': { // save settings
	BZDB.setInt("saveSettings", listHUD->getIndex());
	break;
    }
    case 'i': { // save identity
	BZDB.setInt("saveIdentity", listHUD->getIndex());
	break;
    }
  }
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>the call exists, use it<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "OptionsMenu.h"

/* system implementation headers */
#include <vector>
#include <string>

/* common implementation headers */
#include "FontManager.h"
#include "StartupInfo.h"
#include "StateDatabase.h"
#include "TextUtils.h"

/* local implementation headers */
#include "MainMenu.h"
#include "HUDDialogStack.h"
#include "ControlPanel.h"
#include "ServerListCache.h"
#include "HUDuiControl.h"
#include "HUDuiLabel.h"
#include "HUDuiList.h"

/* FIXME - from playing.h */
StartupInfo* getStartupInfo();
extern ControlPanel* controlPanel;

OptionsMenu::OptionsMenu() : guiOptionsMenu(NULL), effectsMenu(NULL),
			     cacheMenu(NULL), saveWorldMenu(NULL),
			     inputMenu(NULL), audioMenu(NULL),
			     displayMenu(NULL)
{
  // cache font face ID
  int fontFace = MainMenu::getFontFace();

  // add controls
  std::vector<HUDuiControl*>& listHUD = getControls();
  HUDuiList* option;
  std::vector<std::string>* options;

  HUDuiLabel* label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setString("Options");
  listHUD.push_back(label);

  inputSetting = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Input Settings");
  listHUD.push_back(label);

  audioSetting = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Audio Settings");
  listHUD.push_back(label);

  displaySetting = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Display Settings");
  listHUD.push_back(label);

  guiOptions = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("GUI Settings");
  listHUD.push_back(label);

  effectsOptions = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Effects Settings");
  listHUD.push_back(label);

  cacheOptions = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Cache Settings");
  listHUD.push_back(label);

  option = new HUDuiList;
  option->setFontFace(fontFace);
  option->setLabel("Save Settings:");
  option->setCallback(callback, (void*)"s");
  options = &option->getList();
  options->push_back(std::string("No"));
  options->push_back(std::string("On Exit"));
  option->update();
  listHUD.push_back(option);

  option = new HUDuiList;
  option->setFontFace(fontFace);
  option->setLabel("Save identity:");
  option->setCallback(callback, (void*)"i");
  options = &option->getList();
  options->push_back(std::string("No"));
  options->push_back(std::string("Username only"));
  options->push_back(std::string("Username and password"));
  option->update();
  listHUD.push_back(option);

  saveWorld = label = new HUDuiLabel;
  label->setFontFace(fontFace);
  label->setLabel("Save World");
  listHUD.push_back(label);

  initNavigation(listHUD, 1, listHUD.size()-1);
}

OptionsMenu::~OptionsMenu()
{
  delete guiOptionsMenu;
  delete effectsMenu;
  delete cacheMenu;
  delete saveWorldMenu;
  delete inputMenu;
  delete audioMenu;
  delete displayMenu;
}

void OptionsMenu::execute()
{
  HUDuiControl* _focus = HUDui::getFocus();
  if (_focus == guiOptions) {
    if (!guiOptionsMenu) guiOptionsMenu = new GUIOptionsMenu;
    HUDDialogStack::get()->push(guiOptionsMenu);
  } else if (_focus == effectsOptions) {
    if (!effectsMenu) effectsMenu = new EffectsMenu;
    HUDDialogStack::get()->push(effectsMenu);
  } else if (_focus == cacheOptions) {
    if (!cacheMenu) cacheMenu = new CacheMenu;
    HUDDialogStack::get()->push(cacheMenu);
  } else if (_focus == saveWorld) {
    if (!saveWorldMenu) saveWorldMenu = new SaveWorldMenu;
    HUDDialogStack::get()->push(saveWorldMenu);
  } else if (_focus == inputSetting) {
    if (!inputMenu) inputMenu = new InputMenu;
    HUDDialogStack::get()->push(inputMenu);
  } else if (_focus == audioSetting) {
    if (!audioMenu) audioMenu = new AudioMenu;
    HUDDialogStack::get()->push(audioMenu);
  } else if (_focus == displaySetting) {
    if (!displayMenu) displayMenu = new DisplayMenu;
    HUDDialogStack::get()->push(displayMenu);
  }
}

void OptionsMenu::resize(int _width, int _height)
{
  int i;
  HUDDialog::resize(_width, _height);

  // use a big font for title, smaller font for the rest
  const float titleFontSize = (float)_height / 15.0f;
  const float fontSize = (float)_height / 45.0f;
  FontManager &fm = FontManager::instance();

  // reposition title
  std::vector<HUDuiControl*>& listHUD = getControls();
  HUDuiLabel* title = (HUDuiLabel*)listHUD[0];
  title->setFontSize(titleFontSize);
  const float titleWidth = fm.getStrLength(MainMenu::getFontFace(), titleFontSize, title->getString());
  const float titleHeight = fm.getStrHeight(MainMenu::getFontFace(), titleFontSize, " ");
  float x = 0.5f * ((float)_width - titleWidth);
  float y = (float)_height - titleHeight;
  title->setPosition(x, y);

  // reposition options in two columns
  x = 0.5f * (float)_width;
  y -= 0.6f * titleHeight;
  const int count = listHUD.size();
  const float h = fm.getStrHeight(MainMenu::getFontFace(), fontSize, " ");
  for (i = 1; i < count; i++) {
    HUDuiControl *ctl = listHUD[i];
    ctl->setFontSize(fontSize);
    ctl->setPosition(x, y);
    if ((i == 6) || (i == 8)) {
      y -= 1.75f * h;
    } else {
      y -= 1.0f * h;
    }
  }

  // load current settings
  i = 7;

  ((HUDuiList*)listHUD[i++])->setIndex(BZDB.evalInt("saveSettings"));
  ((HUDuiList*)listHUD[i++])->setIndex(BZDB.evalInt("saveIdentity"));
}

void OptionsMenu::callback(HUDuiControl* w, void* data)
{
  HUDuiList* listHUD = (HUDuiList*)w;

  switch (((const char*)data)[0]) {
    case 's': { // save settings
	BZDB.setInt("saveSettings", listHUD->getIndex());
	break;
    }
    case 'i': { // save identity
	BZDB.setInt("saveIdentity", listHUD->getIndex());
	break;
    }
  }
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/rtp_rtcp/source/ulpfec_receiver_impl.h"

#include <memory>
#include <utility>

#include "api/scoped_refptr.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/logging.h"
#include "rtc_base/time_utils.h"

namespace webrtc {

std::unique_ptr<UlpfecReceiver> UlpfecReceiver::Create(
    uint32_t ssrc,
    RecoveredPacketReceiver* callback,
    rtc::ArrayView<const RtpExtension> extensions) {
  return std::make_unique<UlpfecReceiverImpl>(ssrc, callback, extensions);
}

UlpfecReceiverImpl::UlpfecReceiverImpl(
    uint32_t ssrc,
    RecoveredPacketReceiver* callback,
    rtc::ArrayView<const RtpExtension> extensions)
    : ssrc_(ssrc),
      extensions_(extensions),
      recovered_packet_callback_(callback),
      fec_(ForwardErrorCorrection::CreateUlpfec(ssrc_)) {}

UlpfecReceiverImpl::~UlpfecReceiverImpl() {
  received_packets_.clear();
  fec_->ResetState(&recovered_packets_);
}

FecPacketCounter UlpfecReceiverImpl::GetPacketCounter() const {
  rtc::CritScope cs(&crit_sect_);
  return packet_counter_;
}

//     0                   1                    2                   3
//     0 1 2 3 4 5 6 7 8 9 0 1 2 3  4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//    |F|   block PT  |  timestamp offset         |   block length    |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
//
// RFC 2198          RTP Payload for Redundant Audio Data    September 1997
//
//    The bits in the header are specified as follows:
//
//    F: 1 bit First bit in header indicates whether another header block
//        follows.  If 1 further header blocks follow, if 0 this is the
//        last header block.
//        If 0 there is only 1 byte RED header
//
//    block PT: 7 bits RTP payload type for this block.
//
//    timestamp offset:  14 bits Unsigned offset of timestamp of this block
//        relative to timestamp given in RTP header.  The use of an unsigned
//        offset implies that redundant data must be sent after the primary
//        data, and is hence a time to be subtracted from the current
//        timestamp to determine the timestamp of the data for which this
//        block is the redundancy.
//
//    block length:  10 bits Length in bytes of the corresponding data
//        block excluding header.

bool UlpfecReceiverImpl::AddReceivedRedPacket(const RtpPacket& rtp_packet,
                                              uint8_t ulpfec_payload_type) {
  if (rtp_packet.Ssrc() != ssrc_) {
    RTC_LOG(LS_WARNING)
        << "Received RED packet with different SSRC than expected; dropping.";
    return false;
  }
  if (rtp_packet.size() > IP_PACKET_SIZE) {
    RTC_LOG(LS_WARNING) << "Received RED packet with length exceeds maximum IP "
                           "packet size; dropping.";
    return false;
  }
  rtc::CritScope cs(&crit_sect_);

  static constexpr uint8_t kRedHeaderLength = 1;

  if (rtp_packet.payload_size() == 0) {
    RTC_LOG(LS_WARNING) << "Corrupt/truncated FEC packet.";
    return false;
  }

  // Remove RED header of incoming packet and store as a virtual RTP packet.
  auto received_packet =
      std::make_unique<ForwardErrorCorrection::ReceivedPacket>();
  received_packet->pkt = new ForwardErrorCorrection::Packet();

  // Get payload type from RED header and sequence number from RTP header.
  uint8_t payload_type = rtp_packet.payload()[0] & 0x7f;
  received_packet->is_fec = payload_type == ulpfec_payload_type;
  received_packet->ssrc = rtp_packet.Ssrc();
  received_packet->seq_num = rtp_packet.SequenceNumber();

  if (rtp_packet.payload()[0] & 0x80) {
    // f bit set in RED header, i.e. there are more than one RED header blocks.
    // WebRTC never generates multiple blocks in a RED packet for FEC.
    RTC_LOG(LS_WARNING) << "More than 1 block in RED packet is not supported.";
    return false;
  }

  ++packet_counter_.num_packets;
  packet_counter_.num_bytes += rtp_packet.size();
  if (packet_counter_.first_packet_time_ms == -1) {
    packet_counter_.first_packet_time_ms = rtc::TimeMillis();
  }

  if (received_packet->is_fec) {
    ++packet_counter_.num_fec_packets;
    // everything behind the RED header
    received_packet->pkt->data =
        rtp_packet.Buffer().Slice(rtp_packet.headers_size() + kRedHeaderLength,
                                  rtp_packet.payload_size() - kRedHeaderLength);
  } else {
    auto red_payload = rtp_packet.payload().subview(kRedHeaderLength);
    received_packet->pkt->data.EnsureCapacity(rtp_packet.headers_size() +
                                              red_payload.size());
    // Copy RTP header.
    received_packet->pkt->data.SetData(rtp_packet.data(),
                                       rtp_packet.headers_size());
    // Set payload type.
    received_packet->pkt->data[1] &= 0x80;          // Reset RED payload type.
    received_packet->pkt->data[1] += payload_type;  // Set media payload type.
    // Copy payload data.
    received_packet->pkt->data.AppendData(red_payload.data(),
                                          red_payload.size());
  }

  if (received_packet->pkt->data.size() > 0) {
    received_packets_.push_back(std::move(received_packet));
  }
  return true;
}

// TODO(nisse): Drop always-zero return value.
int32_t UlpfecReceiverImpl::ProcessReceivedFec() {
  crit_sect_.Enter();

  // If we iterate over |received_packets_| and it contains a packet that cause
  // us to recurse back to this function (for example a RED packet encapsulating
  // a RED packet), then we will recurse forever. To avoid this we swap
  // |received_packets_| with an empty vector so that the next recursive call
  // wont iterate over the same packet again. This also solves the problem of
  // not modifying the vector we are currently iterating over (packets are added
  // in AddReceivedRedPacket).
  std::vector<std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>>
      received_packets;
  received_packets.swap(received_packets_);

  for (const auto& received_packet : received_packets) {
    // Send received media packet to VCM.
    if (!received_packet->is_fec) {
      ForwardErrorCorrection::Packet* packet = received_packet->pkt;
      crit_sect_.Leave();
      recovered_packet_callback_->OnRecoveredPacket(packet->data.data(),
                                                    packet->data.size());
      crit_sect_.Enter();
      // Create a packet with the buffer to modify it.
      RtpPacketReceived rtp_packet;
      const uint8_t* const original_data = packet->data.cdata();
      rtp_packet.Parse(packet->data);
      rtp_packet.IdentifyExtensions(extensions_);
      // Reset buffer reference, so zeroing would work on a buffer with a
      // single reference.
      packet->data = rtc::CopyOnWriteBuffer(0);
      rtp_packet.ZeroMutableExtensions();
      packet->data = rtp_packet.Buffer();
      // Ensure that zeroing of extensions was done in place.
      RTC_DCHECK_EQ(packet->data.cdata(), original_data);
    }
    fec_->DecodeFec(*received_packet, &recovered_packets_);
  }

  // Send any recovered media packets to VCM.
  for (const auto& recovered_packet : recovered_packets_) {
    if (recovered_packet->returned) {
      // Already sent to the VCM and the jitter buffer.
      continue;
    }
    ForwardErrorCorrection::Packet* packet = recovered_packet->pkt;
    ++packet_counter_.num_recovered_packets;
    // Set this flag first; in case the recovered packet carries a RED
    // header, OnRecoveredPacket will recurse back here.
    recovered_packet->returned = true;
    crit_sect_.Leave();
    recovered_packet_callback_->OnRecoveredPacket(packet->data.data(),
                                                  packet->data.size());
    crit_sect_.Enter();
  }

  crit_sect_.Leave();
  return 0;
}

}  // namespace webrtc
<commit_msg>In ulpfec receiver check for malformed packets to avoid DCHECKS tirggering<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/rtp_rtcp/source/ulpfec_receiver_impl.h"

#include <memory>
#include <utility>

#include "api/scoped_refptr.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/logging.h"
#include "rtc_base/time_utils.h"

namespace webrtc {

std::unique_ptr<UlpfecReceiver> UlpfecReceiver::Create(
    uint32_t ssrc,
    RecoveredPacketReceiver* callback,
    rtc::ArrayView<const RtpExtension> extensions) {
  return std::make_unique<UlpfecReceiverImpl>(ssrc, callback, extensions);
}

UlpfecReceiverImpl::UlpfecReceiverImpl(
    uint32_t ssrc,
    RecoveredPacketReceiver* callback,
    rtc::ArrayView<const RtpExtension> extensions)
    : ssrc_(ssrc),
      extensions_(extensions),
      recovered_packet_callback_(callback),
      fec_(ForwardErrorCorrection::CreateUlpfec(ssrc_)) {}

UlpfecReceiverImpl::~UlpfecReceiverImpl() {
  received_packets_.clear();
  fec_->ResetState(&recovered_packets_);
}

FecPacketCounter UlpfecReceiverImpl::GetPacketCounter() const {
  rtc::CritScope cs(&crit_sect_);
  return packet_counter_;
}

//     0                   1                    2                   3
//     0 1 2 3 4 5 6 7 8 9 0 1 2 3  4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//    |F|   block PT  |  timestamp offset         |   block length    |
//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
//
// RFC 2198          RTP Payload for Redundant Audio Data    September 1997
//
//    The bits in the header are specified as follows:
//
//    F: 1 bit First bit in header indicates whether another header block
//        follows.  If 1 further header blocks follow, if 0 this is the
//        last header block.
//        If 0 there is only 1 byte RED header
//
//    block PT: 7 bits RTP payload type for this block.
//
//    timestamp offset:  14 bits Unsigned offset of timestamp of this block
//        relative to timestamp given in RTP header.  The use of an unsigned
//        offset implies that redundant data must be sent after the primary
//        data, and is hence a time to be subtracted from the current
//        timestamp to determine the timestamp of the data for which this
//        block is the redundancy.
//
//    block length:  10 bits Length in bytes of the corresponding data
//        block excluding header.

bool UlpfecReceiverImpl::AddReceivedRedPacket(const RtpPacket& rtp_packet,
                                              uint8_t ulpfec_payload_type) {
  if (rtp_packet.Ssrc() != ssrc_) {
    RTC_LOG(LS_WARNING)
        << "Received RED packet with different SSRC than expected; dropping.";
    return false;
  }
  if (rtp_packet.size() > IP_PACKET_SIZE) {
    RTC_LOG(LS_WARNING) << "Received RED packet with length exceeds maximum IP "
                           "packet size; dropping.";
    return false;
  }
  rtc::CritScope cs(&crit_sect_);

  static constexpr uint8_t kRedHeaderLength = 1;

  if (rtp_packet.payload_size() == 0) {
    RTC_LOG(LS_WARNING) << "Corrupt/truncated FEC packet.";
    return false;
  }

  // Remove RED header of incoming packet and store as a virtual RTP packet.
  auto received_packet =
      std::make_unique<ForwardErrorCorrection::ReceivedPacket>();
  received_packet->pkt = new ForwardErrorCorrection::Packet();

  // Get payload type from RED header and sequence number from RTP header.
  uint8_t payload_type = rtp_packet.payload()[0] & 0x7f;
  received_packet->is_fec = payload_type == ulpfec_payload_type;
  received_packet->ssrc = rtp_packet.Ssrc();
  received_packet->seq_num = rtp_packet.SequenceNumber();

  if (rtp_packet.payload()[0] & 0x80) {
    // f bit set in RED header, i.e. there are more than one RED header blocks.
    // WebRTC never generates multiple blocks in a RED packet for FEC.
    RTC_LOG(LS_WARNING) << "More than 1 block in RED packet is not supported.";
    return false;
  }

  ++packet_counter_.num_packets;
  packet_counter_.num_bytes += rtp_packet.size();
  if (packet_counter_.first_packet_time_ms == -1) {
    packet_counter_.first_packet_time_ms = rtc::TimeMillis();
  }

  if (received_packet->is_fec) {
    ++packet_counter_.num_fec_packets;
    // everything behind the RED header
    received_packet->pkt->data =
        rtp_packet.Buffer().Slice(rtp_packet.headers_size() + kRedHeaderLength,
                                  rtp_packet.payload_size() - kRedHeaderLength);
  } else {
    auto red_payload = rtp_packet.payload().subview(kRedHeaderLength);
    received_packet->pkt->data.EnsureCapacity(rtp_packet.headers_size() +
                                              red_payload.size());
    // Copy RTP header.
    received_packet->pkt->data.SetData(rtp_packet.data(),
                                       rtp_packet.headers_size());
    // Set payload type.
    received_packet->pkt->data[1] &= 0x80;          // Reset RED payload type.
    received_packet->pkt->data[1] += payload_type;  // Set media payload type.
    // Copy payload data.
    received_packet->pkt->data.AppendData(red_payload.data(),
                                          red_payload.size());
  }

  if (received_packet->pkt->data.size() > 0) {
    received_packets_.push_back(std::move(received_packet));
  }
  return true;
}

// TODO(nisse): Drop always-zero return value.
int32_t UlpfecReceiverImpl::ProcessReceivedFec() {
  crit_sect_.Enter();

  // If we iterate over |received_packets_| and it contains a packet that cause
  // us to recurse back to this function (for example a RED packet encapsulating
  // a RED packet), then we will recurse forever. To avoid this we swap
  // |received_packets_| with an empty vector so that the next recursive call
  // wont iterate over the same packet again. This also solves the problem of
  // not modifying the vector we are currently iterating over (packets are added
  // in AddReceivedRedPacket).
  std::vector<std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>>
      received_packets;
  received_packets.swap(received_packets_);

  for (const auto& received_packet : received_packets) {
    // Send received media packet to VCM.
    if (!received_packet->is_fec) {
      ForwardErrorCorrection::Packet* packet = received_packet->pkt;
      crit_sect_.Leave();
      recovered_packet_callback_->OnRecoveredPacket(packet->data.data(),
                                                    packet->data.size());
      crit_sect_.Enter();
      // Create a packet with the buffer to modify it.
      RtpPacketReceived rtp_packet;
      const uint8_t* const original_data = packet->data.cdata();
      if (!rtp_packet.Parse(packet->data)) {
        RTC_LOG(LS_WARNING) << "Corrupted media packet";
      } else {
        rtp_packet.IdentifyExtensions(extensions_);
        // Reset buffer reference, so zeroing would work on a buffer with a
        // single reference.
        packet->data = rtc::CopyOnWriteBuffer(0);
        rtp_packet.ZeroMutableExtensions();
        packet->data = rtp_packet.Buffer();
        // Ensure that zeroing of extensions was done in place.
        RTC_DCHECK_EQ(packet->data.cdata(), original_data);
      }
    }
    fec_->DecodeFec(*received_packet, &recovered_packets_);
  }

  // Send any recovered media packets to VCM.
  for (const auto& recovered_packet : recovered_packets_) {
    if (recovered_packet->returned) {
      // Already sent to the VCM and the jitter buffer.
      continue;
    }
    ForwardErrorCorrection::Packet* packet = recovered_packet->pkt;
    ++packet_counter_.num_recovered_packets;
    // Set this flag first; in case the recovered packet carries a RED
    // header, OnRecoveredPacket will recurse back here.
    recovered_packet->returned = true;
    crit_sect_.Leave();
    recovered_packet_callback_->OnRecoveredPacket(packet->data.data(),
                                                  packet->data.size());
    crit_sect_.Enter();
  }

  crit_sect_.Leave();
  return 0;
}

}  // namespace webrtc
<|endoftext|>


<commit_before>/*******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 1       *
*                (c) 2006-2007 MGH, INRIA, USTL, UJF, CNRS                     *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Contact information: contact@sofa-framework.org                              *
*                                                                              *
* Authors: J. Allard, P-J. Bensoussan, S. Cotin, C. Duriez, H. Delingette,     *
* F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza, M. Nesme, P. Neumann,        *
* and F. Poyer                                                                 *
*******************************************************************************/
#include <sofa/component/visualmodel/OglModel.h>
#include <sofa/helper/gl/RAII.h>
#include <sofa/helper/vector.h>
#include <sofa/defaulttype/Quat.h>
#include <sofa/core/ObjectFactory.h>
#include <sofa/component/topology/MeshTopology.h>
#include <sstream>

namespace sofa
{

namespace component
{

namespace visualmodel
{

using namespace sofa::defaulttype;

SOFA_DECL_CLASS(OglModel)

int OglModelClass = core::RegisterObject("Generic visual model for OpenGL display")
        .add< OglModel >()
        ;

OglModel::OglModel()
    : tex(NULL)
{
}

OglModel::~OglModel()
{
    if (tex!=NULL) delete tex;
}

void OglModel::internalDraw()
{
    /*if (getContext()->getMainTopology())
    {
        int nbp = getContext()->get<core::componentmodel::behavior::BaseMechanicalState>()->getSize();
        int nbv = vertices.size();
        if (nbp != nbv)
        {
            std::cerr << "nbp mismatch: "<<nbp<<" "<<nbv<<std::endl;
        }
    }*/
    //std::cerr<<" OglModel::draw()"<<std::endl;
    if (!getContext()->getShowVisualModels()) return;
    if (getContext()->getShowWireFrame())
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    glEnable(GL_LIGHTING);

    //Enable<GL_BLEND> blending;
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
    glColor3f(1.0 , 1.0, 1.0);
    Vec4f ambient = material.getValue().useAmbient?material.getValue().ambient:Vec4f();
    Vec4f diffuse = material.getValue().useDiffuse?material.getValue().diffuse:Vec4f();
    Vec4f specular = material.getValue().useSpecular?material.getValue().specular:Vec4f();
    Vec4f emissive = material.getValue().useEmissive?material.getValue().emissive:Vec4f();
    float shininess = material.getValue().useShininess?material.getValue().shininess:45;

    if (isTransparent())
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glDepthMask(GL_FALSE);
        emissive[3] = diffuse[3];
        ambient[3] = 0;
//	diffuse[3] = 0;
//	specular[3] = 0;
    }
    glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, ambient.ptr());
    glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.ptr());
    glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular.ptr());
    glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emissive.ptr());
    glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shininess);

    glVertexPointer (3, GL_FLOAT, 0, vertices.getData());
    glNormalPointer (GL_FLOAT, 0, vnormals.getData());
    glEnableClientState(GL_NORMAL_ARRAY);
    if (tex)
    {
        glEnable(GL_TEXTURE_2D);
        tex->bind();
        glTexCoordPointer(2, GL_FLOAT, 0, vtexcoords.getData());
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    }

    for (unsigned int i=0; i<xforms.size(); i++)
    {
        float matrix[16];
        xforms[i].writeOpenGlMatrix(matrix);
        glPushMatrix();
        glMultMatrixf(matrix);

        if (!triangles.empty())
            glDrawElements(GL_TRIANGLES, triangles.size() * 3, GL_UNSIGNED_INT, triangles.getData());
        if (!quads.empty())
            glDrawElements(GL_QUADS, quads.size() * 4, GL_UNSIGNED_INT, quads.getData());

        glPopMatrix();
    }
    if (tex)
    {
        tex->unbind();
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisable(GL_TEXTURE_2D);
    }
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisable(GL_LIGHTING);
    if (isTransparent())
    {
        glDisable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        //glBlendFunc(GL_ONE, GL_ZERO);
        glDepthMask(GL_TRUE);
    }

    if (getContext()->getShowWireFrame())
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    if (getContext()->getShowNormals())
    {
        glColor3f (1.0, 1.0, 1.0);
        for (unsigned int i=0; i<xforms.size(); i++)
        {
            float matrix[16];
            xforms[i].writeOpenGlMatrix(matrix);
            glPushMatrix();
            glMultMatrixf(matrix);

            for (unsigned int i = 0; i < vertices.size(); i++)
            {
                glBegin(GL_LINES);
                glVertex3fv (vertices[i].ptr());
                Coord p = vertices[i] + vnormals[i];
                glVertex3fv (p.ptr());
                glEnd();
            }

            glPopMatrix();
        }
    }

}

bool OglModel::loadTexture(const std::string& filename)
{
    helper::io::Image *img = helper::io::Image::Create(filename);
    if (!img)
        return false;
    tex = new helper::gl::Texture(img);
    return true;
}

void OglModel::initTextures()
{
    if (tex)
    {
        tex->init();
    }
}

} // namespace visualmodel

} // namespace component

} // namespace sofa

<commit_msg>r1982/sofa-dev : Fix : transparence <commit_after>/*******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 1       *
*                (c) 2006-2007 MGH, INRIA, USTL, UJF, CNRS                     *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Contact information: contact@sofa-framework.org                              *
*                                                                              *
* Authors: J. Allard, P-J. Bensoussan, S. Cotin, C. Duriez, H. Delingette,     *
* F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza, M. Nesme, P. Neumann,        *
* and F. Poyer                                                                 *
*******************************************************************************/
#include <sofa/component/visualmodel/OglModel.h>
#include <sofa/helper/gl/RAII.h>
#include <sofa/helper/vector.h>
#include <sofa/defaulttype/Quat.h>
#include <sofa/core/ObjectFactory.h>
#include <sofa/component/topology/MeshTopology.h>
#include <sstream>

namespace sofa
{

namespace component
{

namespace visualmodel
{

using namespace sofa::defaulttype;

SOFA_DECL_CLASS(OglModel)

int OglModelClass = core::RegisterObject("Generic visual model for OpenGL display")
        .add< OglModel >()
        ;

OglModel::OglModel()
    : tex(NULL)
{
}

OglModel::~OglModel()
{
    if (tex!=NULL) delete tex;
}

void OglModel::internalDraw()
{
    /*if (getContext()->getMainTopology())
    {
        int nbp = getContext()->get<core::componentmodel::behavior::BaseMechanicalState>()->getSize();
        int nbv = vertices.size();
        if (nbp != nbv)
        {
            std::cerr << "nbp mismatch: "<<nbp<<" "<<nbv<<std::endl;
        }
    }*/
    //std::cerr<<" OglModel::draw()"<<std::endl;
    if (!getContext()->getShowVisualModels()) return;
    if (getContext()->getShowWireFrame())
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    glEnable(GL_LIGHTING);

    //Enable<GL_BLEND> blending;
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
    glColor3f(1.0 , 1.0, 1.0);
    Vec4f ambient = material.getValue().useAmbient?material.getValue().ambient:Vec4f();
    Vec4f diffuse = material.getValue().useDiffuse?material.getValue().diffuse:Vec4f();
    Vec4f specular = material.getValue().useSpecular?material.getValue().specular:Vec4f();
    Vec4f emissive = material.getValue().useEmissive?material.getValue().emissive:Vec4f();
    float shininess = material.getValue().useShininess?material.getValue().shininess:45;

    glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, ambient.ptr());
    glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.ptr());
    glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular.ptr());
    glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emissive.ptr());
    glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shininess);

    glVertexPointer (3, GL_FLOAT, 0, vertices.getData());
    glNormalPointer (GL_FLOAT, 0, vnormals.getData());
    glEnableClientState(GL_NORMAL_ARRAY);
    if (tex)
    {
        glEnable(GL_TEXTURE_2D);
        tex->bind();
        glTexCoordPointer(2, GL_FLOAT, 0, vtexcoords.getData());
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    }

    if (isTransparent())
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
        glDepthMask(GL_FALSE);
        emissive[3] = diffuse[3];
        ambient[3] = 0;
//	diffuse[3] = 0;
//	specular[3] = 0;

        for (unsigned int i=0; i<xforms.size(); i++)
        {
            float matrix[16];
            xforms[i].writeOpenGlMatrix(matrix);
            glPushMatrix();
            glMultMatrixf(matrix);

            if (!triangles.empty())
                glDrawElements(GL_TRIANGLES, triangles.size() * 3, GL_UNSIGNED_INT, triangles.getData());
            if (!quads.empty())
                glDrawElements(GL_QUADS, quads.size() * 4, GL_UNSIGNED_INT, quads.getData());

            glPopMatrix();
        }
        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    }

    for (unsigned int i=0; i<xforms.size(); i++)
    {
        float matrix[16];
        xforms[i].writeOpenGlMatrix(matrix);
        glPushMatrix();
        glMultMatrixf(matrix);

        if (!triangles.empty())
            glDrawElements(GL_TRIANGLES, triangles.size() * 3, GL_UNSIGNED_INT, triangles.getData());
        if (!quads.empty())
            glDrawElements(GL_QUADS, quads.size() * 4, GL_UNSIGNED_INT, quads.getData());

        glPopMatrix();
    }
    if (tex)
    {
        tex->unbind();
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisable(GL_TEXTURE_2D);
    }
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisable(GL_LIGHTING);
    if (isTransparent())
    {
        glDisable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        //glBlendFunc(GL_ONE, GL_ZERO);
        glDepthMask(GL_TRUE);
    }

    if (getContext()->getShowWireFrame())
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    if (getContext()->getShowNormals())
    {
        glColor3f (1.0, 1.0, 1.0);
        for (unsigned int i=0; i<xforms.size(); i++)
        {
            float matrix[16];
            xforms[i].writeOpenGlMatrix(matrix);
            glPushMatrix();
            glMultMatrixf(matrix);

            for (unsigned int i = 0; i < vertices.size(); i++)
            {
                glBegin(GL_LINES);
                glVertex3fv (vertices[i].ptr());
                Coord p = vertices[i] + vnormals[i];
                glVertex3fv (p.ptr());
                glEnd();
            }

            glPopMatrix();
        }
    }

}

bool OglModel::loadTexture(const std::string& filename)
{
    helper::io::Image *img = helper::io::Image::Create(filename);
    if (!img)
        return false;
    tex = new helper::gl::Texture(img);
    return true;
}

void OglModel::initTextures()
{
    if (tex)
    {
        tex->init();
    }
}

} // namespace visualmodel

} // namespace component

} // namespace sofa

<|endoftext|>