<commit_before>#include <iostream>

#include "RamLib.h"
#include "Parent.h"

using namespace std;
using namespace FEIND;

ErrCode RamLib::AddPCs(const Kza parent, const int csType,
		       const std::vector<double>& cs)
{
  Data[parent].CrossSections[csType] = cs;
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddSpectrum(const Kza parent, const int specType,
			    const Spectrum& spec)
{
  Data[parent].SpecList[specType] = spec;
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddDecayEnergy(const Kza parent, const int enType,
			       const double energy)
{
  Data[parent].DecayEnergies[enType] = energy;
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddSecPath(const Kza parent, const Kza daughter,
			   const Path& path)
{
  Data[parent].Secondary[daughter].PathList.push_back(path);
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddPath(const Kza parent, const Kza daughter, const Path& path)
{
  Data[parent].Daughters[daughter].PathList.push_back(path);
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddDCs(const Kza parent, const Kza daughter, const int csType,
		       const std::vector<double>& cs)
{
  Data[parent].Daughters[daughter].CrossSections[csType] = cs;
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddDecayConstant(Kza parent, const double constant)
{
  Data[parent].DecayConstant = constant;
  return FEC_NO_ERROR;
}

// ErrCode RamLib::AddBranchingRatio(const Kza parent, const Kza daughter,
// 				  const double br)
// {
//   Data[parent].Daughters[daughter].BranchingRatio = br;
//   return FEC_NO_ERROR;
// }

// ErrCode RamLib::AddDecayMode(const Kza parent, const int mode, const int dIso)
// {
//   if(mode != SPONTANEOUS_FISSION)
//     {
//       int daughter = DecayModetoKza(mode,dIso,parent);
//       Data[parent].Daughters[daughter].DecayMode = dIso;
//     }

//   return FEC_NO_ERROR;
// }

ErrCode RamLib::AddFissionYield(const Kza parent, const Kza daughter,
				const int fissionType, const double yield)
{
  Data[parent].Daughters[daughter].FissionYield[fissionType] = yield;
  return FEC_NO_ERROR;
}

vector<double> RamLib::GetPCs(Kza parent, int csType)
{
  return Data[parent].CrossSections[csType];
}

double RamLib::GetBratio(Kza parent, Kza daughter)
{
  return Data[parent].Daughters[daughter].BranchingRatio;
}

double RamLib::GetSecBratio(Kza parent, Kza sec_daughter)
{
  return Data[parent].Secondary[sec_daughter].BranchingRatio;
}

double RamLib::GetDecayConstant(Kza parent)
{
  return Data[parent].DecayConstant;

}

double RamLib::GetDecayEnergy(Kza parent, Kza enType)
{
  return Data[parent].DecayEnergies[enType];
}

vector<pair<double,double> > RamLib::GetDiscreteSpec(Kza parent, int specType)
{
  return Data[parent].SpecList[specType].Discrete;
}

vector<pair<double,double> >
RamLib::GetFissionYield(Kza parent, int fissionType)
{
  map<int,Daughter>::iterator iter = Data[parent].Daughters.begin();
  vector<pair<double,double> > ret;

  cout << "Start\n";

  while(iter != Data[parent].Daughters.end())
    {
      if(iter->second.FissionYield[fissionType])
	{
	  ret.push_back(pair<double,double>
			(iter->first, iter->second.FissionYield[fissionType]));
	}

      cout << iter->first << '\t' << iter->second.FissionYield[fissionType]
	   << endl;

      iter++;
    }

  return ret;
}

double RamLib::GetFissionYield(Kza parent, Kza daughter, int fissionType)
{
  return Data[parent].Daughters[daughter].FissionYield[fissionType];
}

vector<Kza> RamLib::Daughters(Kza parent)
{
  map<int,Daughter>::iterator iter = Data[parent].Daughters.begin();
  vector<Kza> ret;

  while(iter != Data[parent].Daughters.end())
    {
      ret.push_back(iter->first);
      iter++;
    }

  return ret;
}

std::vector<Kza> RamLib::SecDaughters(Kza parent)
{
  map<int,Daughter>::iterator iter = Data[parent].Secondary.begin();
  vector<Kza> ret;

  while(iter != Data[parent].Secondary.end())
    {
      ret.push_back(iter->first);
      iter++;
    }

  return ret;
}

ErrCode RamLib::AddDecayMode(Kza parent, int decayMode, int dIso, double br)
{
  Kza sec;
  Kza daughter = DecayModetoKza(decayMode, dIso, parent, sec);

  if(decayMode != SPONTANEOUS_FISSION)
    {
      Data[parent].Daughters[daughter].DecayMode = decayMode;
      Data[parent].Daughters[daughter].BranchingRatio = br;
    }
  else
    {
      Data[parent].Sfbr = br;
    }

  if(sec)
    {
      Data[parent].Secondary[sec].DecayMode = decayMode;
      Data[parent].Secondary[sec].BranchingRatio = br;
    }

  return FEC_NO_ERROR;
}

vector<double> RamLib::GetDCs(Kza parent, Kza daughter, int csType)
{
  return Data[parent].Daughters[daughter].CrossSections[csType];
}

ErrCode RamLib::LambdaEff(Kza parent, const vector<double>& flux,
			  double& result)
{
  int i, j;
  vector<Kza> d_kzas = Daughters(parent);
  vector<double> cs;

  result = 0;

  for(i = 0; i < d_kzas.size(); i++)
    {

      // Check to see if there is a total cross section for this daughter:
      cs = GetDCs(parent, d_kzas[i], TOTAL_CS);

      if(cs.size())
	{
	  // Make sure correct group structure:
	  if(cs.size() != flux.size()) return FEC_BAD_GROUP_STRUCT;

	  for(j = 0; j < flux.size(); j++)
	    {
	      result += flux[j]*cs[j];
	    }
	}

    }
  //  Convert from barns:
  result *= 1E-24;

  // Add decay contribution:
  result += GetDecayConstant(parent);

  return FEC_NO_ERROR;
}

ErrCode RamLib::LambdaEff(Kza parent, Kza daughter,
			  const vector<double>& flux, double& result)
{
  int i;

  vector<double> cs = GetDCs(parent,daughter,TOTAL_CS);

  result = 0;

  if(cs.size())
    {
      if(cs.size() != flux.size()) return FEC_BAD_GROUP_STRUCT;

      for(i = 0; i < flux.size(); i++)
	{
	  result += flux[i]*cs[i];
	}
    }

  result *= 1E-24;

  result += GetDecayConstant(parent)*GetBratio(parent,daughter);

  return FEC_NO_ERROR;
}

double RamLib::LambdaEff(Kza parent, const std::vector<double>& flux,
			 vector<Kza>& priDs, vector<double>& priDsLambda,
			 vector<Kza>& secDs, vector<double>& secDsLambda)
{
  double decay_const = GetDecayConstant(parent);
  double total = decay_const;
  int i,j;

  priDs = Daughters(parent);
  secDs = SecDaughters(parent);

  priDsLambda.assign(priDs.size(), 0.0);
  secDsLambda.assign(secDs.size(), 0.0);

  vector<double> cs;

  for(i = 0; i < priDs.size(); i++)
    {
      cs = GetDCs(parent, priDs[i], TOTAL_CS);

      if(cs.size())
	{

	  for(j = 0; j < flux.size(); j++)
	    {
	      priDsLambda[i] += cs[j]*flux[j];
	    }
	}

      total += priDsLambda[i];
    }

  total += decay_const;

  for(i = 0; i < secDs.size(); i++)
    {
      cs = GetSec(parent, secDs[i], TOTAL_CS);

      if(cs.size())
	{
	  for(j = 0; j < flux.size(); j++)
	    {
	      secDsLambda[i] += cs[j]*flux[j];
	    }
	}

      secDsLambda[i] += decay_const * GetSecBratio(parent, secDs[i]);
    }

  return total;
}
<commit_msg>Fixed a bug on total effective lambda by Milad<commit_after>#include <iostream>

#include "RamLib.h"
#include "Parent.h"

using namespace std;
using namespace FEIND;

ErrCode RamLib::AddPCs(const Kza parent, const int csType,
		       const std::vector<double>& cs)
{
  Data[parent].CrossSections[csType] = cs;
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddSpectrum(const Kza parent, const int specType,
			    const Spectrum& spec)
{
  Data[parent].SpecList[specType] = spec;
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddDecayEnergy(const Kza parent, const int enType,
			       const double energy)
{
  Data[parent].DecayEnergies[enType] = energy;
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddSecPath(const Kza parent, const Kza daughter,
			   const Path& path)
{
  Data[parent].Secondary[daughter].PathList.push_back(path);
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddPath(const Kza parent, const Kza daughter, const Path& path)
{
  Data[parent].Daughters[daughter].PathList.push_back(path);
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddDCs(const Kza parent, const Kza daughter, const int csType,
		       const std::vector<double>& cs)
{
  Data[parent].Daughters[daughter].CrossSections[csType] = cs;
  return FEC_NO_ERROR;
}

ErrCode RamLib::AddDecayConstant(Kza parent, const double constant)
{
  Data[parent].DecayConstant = constant;
  return FEC_NO_ERROR;
}

// ErrCode RamLib::AddBranchingRatio(const Kza parent, const Kza daughter,
// 				  const double br)
// {
//   Data[parent].Daughters[daughter].BranchingRatio = br;
//   return FEC_NO_ERROR;
// }

// ErrCode RamLib::AddDecayMode(const Kza parent, const int mode, const int dIso)
// {
//   if(mode != SPONTANEOUS_FISSION)
//     {
//       int daughter = DecayModetoKza(mode,dIso,parent);
//       Data[parent].Daughters[daughter].DecayMode = dIso;
//     }

//   return FEC_NO_ERROR;
// }

ErrCode RamLib::AddFissionYield(const Kza parent, const Kza daughter,
				const int fissionType, const double yield)
{
  Data[parent].Daughters[daughter].FissionYield[fissionType] = yield;
  return FEC_NO_ERROR;
}

vector<double> RamLib::GetPCs(Kza parent, int csType)
{
  return Data[parent].CrossSections[csType];
}

double RamLib::GetBratio(Kza parent, Kza daughter)
{
  return Data[parent].Daughters[daughter].BranchingRatio;
}

double RamLib::GetSecBratio(Kza parent, Kza sec_daughter)
{
  return Data[parent].Secondary[sec_daughter].BranchingRatio;
}

double RamLib::GetDecayConstant(Kza parent)
{
  return Data[parent].DecayConstant;

}

double RamLib::GetDecayEnergy(Kza parent, Kza enType)
{
  return Data[parent].DecayEnergies[enType];
}

vector<pair<double,double> > RamLib::GetDiscreteSpec(Kza parent, int specType)
{
  return Data[parent].SpecList[specType].Discrete;
}

vector<pair<double,double> >
RamLib::GetFissionYield(Kza parent, int fissionType)
{
  map<int,Daughter>::iterator iter = Data[parent].Daughters.begin();
  vector<pair<double,double> > ret;

  cout << "Start\n";

  while(iter != Data[parent].Daughters.end())
    {
      if(iter->second.FissionYield[fissionType])
	{
	  ret.push_back(pair<double,double>
			(iter->first, iter->second.FissionYield[fissionType]));
	}

      cout << iter->first << '\t' << iter->second.FissionYield[fissionType]
	   << endl;

      iter++;
    }

  return ret;
}

double RamLib::GetFissionYield(Kza parent, Kza daughter, int fissionType)
{
  return Data[parent].Daughters[daughter].FissionYield[fissionType];
}

vector<Kza> RamLib::Daughters(Kza parent)
{
  map<int,Daughter>::iterator iter = Data[parent].Daughters.begin();
  vector<Kza> ret;

  while(iter != Data[parent].Daughters.end())
    {
      ret.push_back(iter->first);
      iter++;
    }

  return ret;
}

std::vector<Kza> RamLib::SecDaughters(Kza parent)
{
  map<int,Daughter>::iterator iter = Data[parent].Secondary.begin();
  vector<Kza> ret;

  while(iter != Data[parent].Secondary.end())
    {
      ret.push_back(iter->first);
      iter++;
    }

  return ret;
}

ErrCode RamLib::AddDecayMode(Kza parent, int decayMode, int dIso, double br)
{
  Kza sec;
  Kza daughter = DecayModetoKza(decayMode, dIso, parent, sec);

  if(decayMode != SPONTANEOUS_FISSION)
    {
      Data[parent].Daughters[daughter].DecayMode = decayMode;
      Data[parent].Daughters[daughter].BranchingRatio = br;
    }
  else
    {
      Data[parent].Sfbr = br;
    }

  if(sec)
    {
      Data[parent].Secondary[sec].DecayMode = decayMode;
      Data[parent].Secondary[sec].BranchingRatio = br;
    }

  return FEC_NO_ERROR;
}

vector<double> RamLib::GetDCs(Kza parent, Kza daughter, int csType)
{
  return Data[parent].Daughters[daughter].CrossSections[csType];
}

ErrCode RamLib::LambdaEff(Kza parent, const vector<double>& flux,
			  double& result)
{
  int i, j;
  vector<Kza> d_kzas = Daughters(parent);
  vector<double> cs;

  result = 0;

  for(i = 0; i < d_kzas.size(); i++)
    {

      // Check to see if there is a total cross section for this daughter:
      cs = GetDCs(parent, d_kzas[i], TOTAL_CS);

      if(cs.size())
	{
	  // Make sure correct group structure:
	  if(cs.size() != flux.size()) return FEC_BAD_GROUP_STRUCT;

	  for(j = 0; j < flux.size(); j++)
	    {
	      result += flux[j]*cs[j];
	    }
	}

    }
  //  Convert from barns:
  result *= 1E-24;

  // Add decay contribution:
  result += GetDecayConstant(parent);

  return FEC_NO_ERROR;
}

ErrCode RamLib::LambdaEff(Kza parent, Kza daughter,
			  const vector<double>& flux, double& result)
{
  int i;

  vector<double> cs = GetDCs(parent,daughter,TOTAL_CS);

  result = 0;

  if(cs.size())
    {
      if(cs.size() != flux.size()) return FEC_BAD_GROUP_STRUCT;

      for(i = 0; i < flux.size(); i++)
	{
	  result += flux[i]*cs[i];
	}
    }

  result *= 1E-24;

  result += GetDecayConstant(parent)*GetBratio(parent,daughter);

  return FEC_NO_ERROR;
}

double RamLib::LambdaEff(Kza parent, const std::vector<double>& flux,
			 vector<Kza>& priDs, vector<double>& priDsLambda,
			 vector<Kza>& secDs, vector<double>& secDsLambda)
{
  double decay_const = GetDecayConstant(parent);
  double total = decay_const;
  int i,j;

  priDs = Daughters(parent);
  secDs = SecDaughters(parent);

  priDsLambda.assign(priDs.size(), 0.0);
  secDsLambda.assign(secDs.size(), 0.0);

  vector<double> cs;

  for(i = 0; i < priDs.size(); i++)
    {
      cs = GetDCs(parent, priDs[i], TOTAL_CS);

      if(cs.size())
	{

	  for(j = 0; j < flux.size(); j++)
	    {
	      priDsLambda[i] += cs[j]*flux[j];
	    }
	}

      total += priDsLambda[i];
      priDsLambda[i] += GetBratio(parent,priDs[i])*decay_const;
    }

  for(i = 0; i < secDs.size(); i++)
    {
      cs = GetSec(parent, secDs[i], TOTAL_CS);

      if(cs.size())
	{
	  for(j = 0; j < flux.size(); j++)
	    {
	      secDsLambda[i] += cs[j]*flux[j];
	    }
	}

      secDsLambda[i] += decay_const * GetSecBratio(parent, secDs[i]);
    }

  return total;
}
<|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.
 */

// This is the implementation of the PacketBuffer class. It is mostly based on
// an STL list. The list is kept sorted at all times so that the next packet to
// decode is at the beginning of the list.

#include "webrtc/modules/audio_coding/neteq4/packet_buffer.h"

#include <algorithm>  // find_if()

#include "webrtc/modules/audio_coding/neteq4/decoder_database.h"
#include "webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h"

namespace webrtc {

// Predicate used when inserting packets in the buffer list.
// Operator() returns true when |packet| goes before |new_packet|.
class NewTimestampIsLarger {
 public:
  explicit NewTimestampIsLarger(const Packet* new_packet)
      : new_packet_(new_packet) {
  }
  bool operator()(Packet* packet) {
    return (*new_packet_ >= *packet);
  }

 private:
  const Packet* new_packet_;
};

// Constructor. The arguments define the maximum number of slots and maximum
// payload memory (excluding RTP headers) that the buffer will accept.
PacketBuffer::PacketBuffer(size_t max_number_of_packets,
                           size_t max_memory_bytes)
    : max_number_of_packets_(max_number_of_packets),
      max_memory_bytes_(max_memory_bytes),
      current_memory_bytes_(0) {
}

// Destructor. All packets in the buffer will be destroyed.
PacketBuffer::~PacketBuffer() {
  Flush();
}

// Flush the buffer. All packets in the buffer will be destroyed.
void PacketBuffer::Flush() {
  DeleteAllPackets(&buffer_);
  current_memory_bytes_ = 0;
}

int PacketBuffer::InsertPacket(Packet* packet) {
  if (!packet || !packet->payload) {
    if (packet) {
      delete packet;
    }
    return kInvalidPacket;
  }

  int return_val = kOK;

  if ((buffer_.size() >= max_number_of_packets_) ||
      (current_memory_bytes_ + packet->payload_length
          > static_cast<int>(max_memory_bytes_))) {
    // Buffer is full. Flush it.
    Flush();
    return_val = kFlushed;
    if ((buffer_.size() >= max_number_of_packets_) ||
        (current_memory_bytes_ + packet->payload_length
            > static_cast<int>(max_memory_bytes_))) {
      // Buffer is still too small for the packet. Either the buffer limits are
      // really small, or the packet is really large. Delete the packet and
      // return an error.
      delete [] packet->payload;
      delete packet;
      return kOversizePacket;
    }
  }

  // Get an iterator pointing to the place in the buffer where the new packet
  // should be inserted. The list is searched from the back, since the most
  // likely case is that the new packet should be near the end of the list.
  PacketList::reverse_iterator rit = std::find_if(
      buffer_.rbegin(), buffer_.rend(),
      NewTimestampIsLarger(packet));
  buffer_.insert(rit.base(), packet);  // Insert the packet at that position.
  current_memory_bytes_ += packet->payload_length;

  return return_val;
}

int PacketBuffer::InsertPacketList(PacketList* packet_list,
                                   const DecoderDatabase& decoder_database,
                                   uint8_t* current_rtp_payload_type,
                                   uint8_t* current_cng_rtp_payload_type) {
  bool flushed = false;
  while (!packet_list->empty()) {
    Packet* packet = packet_list->front();
    if (decoder_database.IsComfortNoise(packet->header.payloadType)) {
      if (*current_cng_rtp_payload_type != 0xFF &&
          *current_cng_rtp_payload_type != packet->header.payloadType) {
        // New CNG payload type implies new codec type.
        *current_rtp_payload_type = 0xFF;
        Flush();
        flushed = true;
      }
      *current_cng_rtp_payload_type = packet->header.payloadType;
    } else if (!decoder_database.IsDtmf(packet->header.payloadType)) {
      // This must be speech.
      if (*current_rtp_payload_type != 0xFF &&
          *current_rtp_payload_type != packet->header.payloadType) {
        *current_cng_rtp_payload_type = 0xFF;
        Flush();
        flushed = true;
      }
      *current_rtp_payload_type = packet->header.payloadType;
    }
    int return_val = InsertPacket(packet);
    packet_list->pop_front();
    if (return_val == kFlushed) {
      // The buffer flushed, but this is not an error. We can still continue.
      flushed = true;
    } else if (return_val != kOK) {
      // An error occurred. Delete remaining packets in list and return.
      DeleteAllPackets(packet_list);
      return return_val;
    }
  }
  return flushed ? kFlushed : kOK;
}

int PacketBuffer::NextTimestamp(uint32_t* next_timestamp) const {
  if (Empty()) {
    return kBufferEmpty;
  }
  if (!next_timestamp) {
    return kInvalidPointer;
  }
  *next_timestamp = buffer_.front()->header.timestamp;
  return kOK;
}

int PacketBuffer::NextHigherTimestamp(uint32_t timestamp,
                                      uint32_t* next_timestamp) const {
  if (Empty()) {
    return kBufferEmpty;
  }
  if (!next_timestamp) {
    return kInvalidPointer;
  }
  PacketList::const_iterator it;
  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
    if ((*it)->header.timestamp >= timestamp) {
      // Found a packet matching the search.
      *next_timestamp = (*it)->header.timestamp;
      return kOK;
    }
  }
  return kNotFound;
}

const RTPHeader* PacketBuffer::NextRtpHeader() const {
  if (Empty()) {
    return NULL;
  }
  return const_cast<const RTPHeader*>(&(buffer_.front()->header));
}

Packet* PacketBuffer::GetNextPacket(int* discard_count) {
  if (Empty()) {
    // Buffer is empty.
    return NULL;
  }

  Packet* packet = buffer_.front();
  // Assert that the packet sanity checks in InsertPacket method works.
  assert(packet && packet->payload);
  buffer_.pop_front();
  current_memory_bytes_ -= packet->payload_length;
  assert(current_memory_bytes_ >= 0);  // Assert bookkeeping is correct.
  // Discard other packets with the same timestamp. These are duplicates or
  // redundant payloads that should not be used.
  if (discard_count) {
    *discard_count = 0;
  }
  while (!Empty() &&
      buffer_.front()->header.timestamp == packet->header.timestamp) {
    if (DiscardNextPacket() != kOK) {
      assert(false);  // Must be ok by design.
    }
    if (discard_count) {
      ++(*discard_count);
    }
  }
  return packet;
}

int PacketBuffer::DiscardNextPacket() {
  if (Empty()) {
    return kBufferEmpty;
  }
  Packet* temp_packet = buffer_.front();
  // Assert that the packet sanity checks in InsertPacket method works.
  assert(temp_packet && temp_packet->payload);
  current_memory_bytes_ -= temp_packet->payload_length;
  assert(current_memory_bytes_ >= 0);  // Assert bookkeeping is correct.
  DeleteFirstPacket(&buffer_);
  return kOK;
}

int PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit) {
  int discard_count = 0;
  while (!Empty() &&
      timestamp_limit != buffer_.front()->header.timestamp &&
      static_cast<uint32_t>(timestamp_limit
                            - buffer_.front()->header.timestamp) <
                            0xFFFFFFFF / 2) {
    if (DiscardNextPacket() != kOK) {
      assert(false);  // Must be ok by design.
    }
    ++discard_count;
  }
  return 0;
}

int PacketBuffer::NumSamplesInBuffer(DecoderDatabase* decoder_database,
                                     int last_decoded_length) const {
  PacketList::const_iterator it;
  int num_samples = 0;
  int last_duration = last_decoded_length;
  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
    Packet* packet = (*it);
    AudioDecoder* decoder =
        decoder_database->GetDecoder(packet->header.payloadType);
    if (decoder) {
      int duration = packet->sync_packet ? last_duration :
          decoder->PacketDuration(packet->payload, packet->payload_length);
      if (duration >= 0) {
        last_duration = duration;  // Save the most up-to-date (valid) duration.
      }
    }
    num_samples += last_duration;
  }
  return num_samples;
}

void PacketBuffer::IncrementWaitingTimes(int inc) {
  PacketList::iterator it;
  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
    (*it)->waiting_time += inc;
  }
}

bool PacketBuffer::DeleteFirstPacket(PacketList* packet_list) {
  if (packet_list->empty()) {
    return false;
  }
  Packet* first_packet = packet_list->front();
  delete [] first_packet->payload;
  delete first_packet;
  packet_list->pop_front();
  return true;
}

void PacketBuffer::DeleteAllPackets(PacketList* packet_list) {
  while (DeleteFirstPacket(packet_list)) {
    // Continue while the list is not empty.
  }
}

void PacketBuffer::BufferStat(int* num_packets,
                              int* max_num_packets,
                              int* current_memory_bytes,
                              int* max_memory_bytes) const {
  *num_packets = static_cast<int>(buffer_.size());
  *max_num_packets = static_cast<int>(max_number_of_packets_);
  *current_memory_bytes = current_memory_bytes_;
  *max_memory_bytes = static_cast<int>(max_memory_bytes_);
}

}  // namespace webrtc
<commit_msg>Removing a variable that was never read<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.
 */

// This is the implementation of the PacketBuffer class. It is mostly based on
// an STL list. The list is kept sorted at all times so that the next packet to
// decode is at the beginning of the list.

#include "webrtc/modules/audio_coding/neteq4/packet_buffer.h"

#include <algorithm>  // find_if()

#include "webrtc/modules/audio_coding/neteq4/decoder_database.h"
#include "webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h"

namespace webrtc {

// Predicate used when inserting packets in the buffer list.
// Operator() returns true when |packet| goes before |new_packet|.
class NewTimestampIsLarger {
 public:
  explicit NewTimestampIsLarger(const Packet* new_packet)
      : new_packet_(new_packet) {
  }
  bool operator()(Packet* packet) {
    return (*new_packet_ >= *packet);
  }

 private:
  const Packet* new_packet_;
};

// Constructor. The arguments define the maximum number of slots and maximum
// payload memory (excluding RTP headers) that the buffer will accept.
PacketBuffer::PacketBuffer(size_t max_number_of_packets,
                           size_t max_memory_bytes)
    : max_number_of_packets_(max_number_of_packets),
      max_memory_bytes_(max_memory_bytes),
      current_memory_bytes_(0) {
}

// Destructor. All packets in the buffer will be destroyed.
PacketBuffer::~PacketBuffer() {
  Flush();
}

// Flush the buffer. All packets in the buffer will be destroyed.
void PacketBuffer::Flush() {
  DeleteAllPackets(&buffer_);
  current_memory_bytes_ = 0;
}

int PacketBuffer::InsertPacket(Packet* packet) {
  if (!packet || !packet->payload) {
    if (packet) {
      delete packet;
    }
    return kInvalidPacket;
  }

  int return_val = kOK;

  if ((buffer_.size() >= max_number_of_packets_) ||
      (current_memory_bytes_ + packet->payload_length
          > static_cast<int>(max_memory_bytes_))) {
    // Buffer is full. Flush it.
    Flush();
    return_val = kFlushed;
    if ((buffer_.size() >= max_number_of_packets_) ||
        (current_memory_bytes_ + packet->payload_length
            > static_cast<int>(max_memory_bytes_))) {
      // Buffer is still too small for the packet. Either the buffer limits are
      // really small, or the packet is really large. Delete the packet and
      // return an error.
      delete [] packet->payload;
      delete packet;
      return kOversizePacket;
    }
  }

  // Get an iterator pointing to the place in the buffer where the new packet
  // should be inserted. The list is searched from the back, since the most
  // likely case is that the new packet should be near the end of the list.
  PacketList::reverse_iterator rit = std::find_if(
      buffer_.rbegin(), buffer_.rend(),
      NewTimestampIsLarger(packet));
  buffer_.insert(rit.base(), packet);  // Insert the packet at that position.
  current_memory_bytes_ += packet->payload_length;

  return return_val;
}

int PacketBuffer::InsertPacketList(PacketList* packet_list,
                                   const DecoderDatabase& decoder_database,
                                   uint8_t* current_rtp_payload_type,
                                   uint8_t* current_cng_rtp_payload_type) {
  bool flushed = false;
  while (!packet_list->empty()) {
    Packet* packet = packet_list->front();
    if (decoder_database.IsComfortNoise(packet->header.payloadType)) {
      if (*current_cng_rtp_payload_type != 0xFF &&
          *current_cng_rtp_payload_type != packet->header.payloadType) {
        // New CNG payload type implies new codec type.
        *current_rtp_payload_type = 0xFF;
        Flush();
        flushed = true;
      }
      *current_cng_rtp_payload_type = packet->header.payloadType;
    } else if (!decoder_database.IsDtmf(packet->header.payloadType)) {
      // This must be speech.
      if (*current_rtp_payload_type != 0xFF &&
          *current_rtp_payload_type != packet->header.payloadType) {
        *current_cng_rtp_payload_type = 0xFF;
        Flush();
        flushed = true;
      }
      *current_rtp_payload_type = packet->header.payloadType;
    }
    int return_val = InsertPacket(packet);
    packet_list->pop_front();
    if (return_val == kFlushed) {
      // The buffer flushed, but this is not an error. We can still continue.
      flushed = true;
    } else if (return_val != kOK) {
      // An error occurred. Delete remaining packets in list and return.
      DeleteAllPackets(packet_list);
      return return_val;
    }
  }
  return flushed ? kFlushed : kOK;
}

int PacketBuffer::NextTimestamp(uint32_t* next_timestamp) const {
  if (Empty()) {
    return kBufferEmpty;
  }
  if (!next_timestamp) {
    return kInvalidPointer;
  }
  *next_timestamp = buffer_.front()->header.timestamp;
  return kOK;
}

int PacketBuffer::NextHigherTimestamp(uint32_t timestamp,
                                      uint32_t* next_timestamp) const {
  if (Empty()) {
    return kBufferEmpty;
  }
  if (!next_timestamp) {
    return kInvalidPointer;
  }
  PacketList::const_iterator it;
  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
    if ((*it)->header.timestamp >= timestamp) {
      // Found a packet matching the search.
      *next_timestamp = (*it)->header.timestamp;
      return kOK;
    }
  }
  return kNotFound;
}

const RTPHeader* PacketBuffer::NextRtpHeader() const {
  if (Empty()) {
    return NULL;
  }
  return const_cast<const RTPHeader*>(&(buffer_.front()->header));
}

Packet* PacketBuffer::GetNextPacket(int* discard_count) {
  if (Empty()) {
    // Buffer is empty.
    return NULL;
  }

  Packet* packet = buffer_.front();
  // Assert that the packet sanity checks in InsertPacket method works.
  assert(packet && packet->payload);
  buffer_.pop_front();
  current_memory_bytes_ -= packet->payload_length;
  assert(current_memory_bytes_ >= 0);  // Assert bookkeeping is correct.
  // Discard other packets with the same timestamp. These are duplicates or
  // redundant payloads that should not be used.
  if (discard_count) {
    *discard_count = 0;
  }
  while (!Empty() &&
      buffer_.front()->header.timestamp == packet->header.timestamp) {
    if (DiscardNextPacket() != kOK) {
      assert(false);  // Must be ok by design.
    }
    if (discard_count) {
      ++(*discard_count);
    }
  }
  return packet;
}

int PacketBuffer::DiscardNextPacket() {
  if (Empty()) {
    return kBufferEmpty;
  }
  Packet* temp_packet = buffer_.front();
  // Assert that the packet sanity checks in InsertPacket method works.
  assert(temp_packet && temp_packet->payload);
  current_memory_bytes_ -= temp_packet->payload_length;
  assert(current_memory_bytes_ >= 0);  // Assert bookkeeping is correct.
  DeleteFirstPacket(&buffer_);
  return kOK;
}

int PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit) {
  while (!Empty() &&
      timestamp_limit != buffer_.front()->header.timestamp &&
      static_cast<uint32_t>(timestamp_limit
                            - buffer_.front()->header.timestamp) <
                            0xFFFFFFFF / 2) {
    if (DiscardNextPacket() != kOK) {
      assert(false);  // Must be ok by design.
    }
  }
  return 0;
}

int PacketBuffer::NumSamplesInBuffer(DecoderDatabase* decoder_database,
                                     int last_decoded_length) const {
  PacketList::const_iterator it;
  int num_samples = 0;
  int last_duration = last_decoded_length;
  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
    Packet* packet = (*it);
    AudioDecoder* decoder =
        decoder_database->GetDecoder(packet->header.payloadType);
    if (decoder) {
      int duration = packet->sync_packet ? last_duration :
          decoder->PacketDuration(packet->payload, packet->payload_length);
      if (duration >= 0) {
        last_duration = duration;  // Save the most up-to-date (valid) duration.
      }
    }
    num_samples += last_duration;
  }
  return num_samples;
}

void PacketBuffer::IncrementWaitingTimes(int inc) {
  PacketList::iterator it;
  for (it = buffer_.begin(); it != buffer_.end(); ++it) {
    (*it)->waiting_time += inc;
  }
}

bool PacketBuffer::DeleteFirstPacket(PacketList* packet_list) {
  if (packet_list->empty()) {
    return false;
  }
  Packet* first_packet = packet_list->front();
  delete [] first_packet->payload;
  delete first_packet;
  packet_list->pop_front();
  return true;
}

void PacketBuffer::DeleteAllPackets(PacketList* packet_list) {
  while (DeleteFirstPacket(packet_list)) {
    // Continue while the list is not empty.
  }
}

void PacketBuffer::BufferStat(int* num_packets,
                              int* max_num_packets,
                              int* current_memory_bytes,
                              int* max_memory_bytes) const {
  *num_packets = static_cast<int>(buffer_.size());
  *max_num_packets = static_cast<int>(max_number_of_packets_);
  *current_memory_bytes = current_memory_bytes_;
  *max_memory_bytes = static_cast<int>(max_memory_bytes_);
}

}  // namespace webrtc
<|endoftext|>


<commit_before>/***********************************
Copyright 2017 Ravishankar Mathur

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
***********************************/

#include "ofcontrols.hpp"

#include <OpenFrames/QWidgetPanel.hpp>
#include <OpenFrames/WindowProxy.hpp>
#include <OpenFrames/Sphere.hpp>

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QListWidget>
#include <QSlider>
#include <QScrollbar>

/// The period of event checking in the main loop (milliseconds)
const double OFControls::MAIN_LOOP_PERIOD = 10;

/// Prose for the text edit control
const char *OFControls::LOREM_IPSUM_DOLOR =
  "This is an example of Qt widgets in an OSG texture. The widgets control the sphere sitting above.";

/// Colors for the sphere demo
const std::map<std::string, osg::Vec4> OFControls::COLORS =
  {
    { "Red",{ 1.0, 0.0, 0.0, 0.0 } },
    { "Green",{ 0.0, 0.5, 0.0, 0.0 } },
    { "Blue",{ 0.0, 0.0, 1.0, 0.0 } },
    { "Purple",{ 1.0, 0.0, 1.0, 0.0 } },
    { "Yellow",{ 1.0, 1.0, 0.0, 0.0 } },
    { "Cyan",{ 0.0, 1.0, 1.0, 0.0 } },
    { "Orange",{ 1.0, 0.5, 0.0, 0.0 } },
    { "Navy",{ 0.0, 0.0, 0.5, 0.0 } },
    { "Gray",{ 0.5, 0.5, 0.5, 0.0 } },
};

/// Default color for the sphere
const char *OFControls::DEFAULT_SPHERE_COLOR = COLORS.begin()->first.c_str();

int main(int argc, char **argv)
{
  // Qt requires that we construct the global QApplication before creating any widgets.
  QApplication app(argc, argv);

  // Configure the default appearance for our VR world
  QFont font = app.font();
  font.setPixelSize(20);
  app.setFont(font);

  // Start main app
  static OFControls controls;
  controls.main(argc, argv);
}

OFControls::OFControls()
{
  // Instantiate and configure OpenFrames objects
  _windowProxy = new OpenFrames::WindowProxy(100, 100, 640, 480, 1, 1, false, false);

  _root = new OpenFrames::ReferenceFrame("root");
  _root->showNameLabel(false);
  _root->showAxes(0U);
  _root->showAxesLabels(0U);

  OpenFrames::QWidgetPanel *panel1 = new OpenFrames::QWidgetPanel("panel");
  panel1->setColor(0.8, 0.8, 0.8, 0.9);
  panel1->setHalfLengths(1.5, 1.2, 0.1);
  panel1->setAttitude(-0.707106781186547, 0.0, 0.0, 0.707106781186547);
  panel1->setPosition(0.0, 0.0, -1.0);
  panel1->showAxes(0U);
  panel1->showAxesLabels(0U);
  panel1->setPixelsPerUnit(100.0);
  _root->addChild(panel1);

  OpenFrames::QWidgetPanel *panel2 = new OpenFrames::QWidgetPanel("panel");
  panel2->setColor(0.8, 0.8, 0.8, 0.9);
  panel2->setHalfLengths(1.5, 1.2, 0.1);
  panel2->setPosition(3.1, 0.0, -1.0);
  panel2->setAttitude(-0.707106781186547, 0.0, 0.0, 0.707106781186547);
  panel2->showAxes(0U);
  panel2->showAxesLabels(0U);
  panel2->setPixelsPerUnit(50.0);
  _root->addChild(panel2);

  OpenFrames::QWidgetPanel *panel3 = new OpenFrames::QWidgetPanel("panel");
  panel3->setColor(0.8, 0.8, 0.8, 0.9);
  panel3->setHalfLengths(1.5, 1.2, 0.1);
  panel3->setPosition(-3.1, 0.0, -1.0);
  panel3->setAttitude(-0.707106781186547, 0.0, 0.0, 0.707106781186547);
  panel3->showAxes(0U);
  panel3->showAxesLabels(0U);
  panel3->setPixelsPerUnit(90.0);
  _root->addChild(panel3);

  _hiddenPanel = new OpenFrames::QWidgetPanel("panel");
  _hiddenPanel->setColor(0.8, 0.8, 0.8, 0.8);
  _hiddenPanel->setHalfLengths(1.5, 1.2, 0.1);
  _hiddenPanel->setPosition(3.1, 0.0, 1.5);
  _hiddenPanel->setAttitude(-0.707106781186547, 0.0, 0.0, 0.707106781186547);
  _hiddenPanel->showAxes(0U);
  _hiddenPanel->showAxesLabels(0U);
  _hiddenPanel->setPixelsPerUnit(50.0);

  _sphere = new OpenFrames::Sphere("sphere");
  _sphere->setPosition(-1.55, 0.0, 1.0);
  _sphere->setColor(COLORS.at(DEFAULT_SPHERE_COLOR));
  _sphere->showNameLabel(false);
  _sphere->showAxes(7U);
  _sphere->showAxesLabels(7U);
  _sphere->setRadius(1.0);
  _root->addChild(_sphere);

  // Create the example controls widget
  QWidget *widget1 = new QWidget;
  widget1->setLayout(new QVBoxLayout);
  QString text(LOREM_IPSUM_DOLOR);
  QLabel *textLabel = new QLabel(text);
  textLabel->setWordWrap(true);
  widget1->layout()->addWidget(textLabel);
  _toggleButton = new QPushButton("Hide Sphere");
  widget1->layout()->addWidget(_toggleButton);
  panel1->setWidget(widget1);

  // Create the example controls widget
  QWidget *widget2 = new QWidget;
  widget2->setLayout(new QVBoxLayout);
  _checkBox = new QCheckBox("Show sphere");
  _checkBox->setChecked(true);
  QCheckBox *moveSphereBox = new QCheckBox("Move sphere");
  widget2->layout()->addWidget(_checkBox);
  widget2->layout()->addWidget(moveSphereBox);
  panel2->setWidget(widget2);

  // Create the example list view
  QWidget *widget3 = new QWidget;
  widget3->setLayout(new QVBoxLayout);
  _list = new QListWidget();
  _list->setIconSize(QSize(30, 30));
  for (auto color = COLORS.begin(); color != COLORS.end(); color++)
  {
    QListWidgetItem *item = new QListWidgetItem(color->first.c_str());
    const osg::Vec4 &osgColor = color->second;
    QColor qColor(round(osgColor[0]*255.0), round(osgColor[1]*255.0), round(osgColor[2]*255.0));
    QFont font = item->font();
    font.setPixelSize(30);
    item->setFont(font);
    QPixmap pixmap(QSize(30, 30));
    pixmap.fill(qColor);
    item->setIcon(QIcon(pixmap));
    _list->addItem(item);
  }
  QList<QListWidgetItem *> matchingItems = _list->findItems(DEFAULT_SPHERE_COLOR, Qt::MatchExactly);
  if (matchingItems.size() > 0)
  {
    _list->setCurrentItem(matchingItems[0]);
  }
  widget3->layout()->addWidget(_list);
  panel3->setWidget(widget3);

  // Create the example controls widget
  QWidget *widget = new QWidget;
  widget->setLayout(new QVBoxLayout);
  QSlider *xSlider = new QSlider(Qt::Horizontal);
  xSlider->setRange(-20, 20);
  QSlider *ySlider = new QSlider(Qt::Horizontal);
  ySlider->setRange(-20, 20);
  QSlider *zSlider = new QSlider(Qt::Horizontal);
  zSlider->setRange(0, 20);
  widget->layout()->addWidget(xSlider);
  widget->layout()->addWidget(ySlider);
  widget->layout()->addWidget(zSlider);
  _hiddenPanel->setWidget(widget);

  // Connect QObject signals to our slots
  connect(moveSphereBox, &QCheckBox::clicked, this, &OFControls::toggleHiddenPanel);
  connect(_toggleButton, &QPushButton::clicked, this, &OFControls::toggleSphere);
  connect(_checkBox, &QCheckBox::clicked, this, &OFControls::toggleSphere);
  connect(_list, &QListWidget::itemActivated, this, &OFControls::setColor);
  connect(_list, &QListWidget::itemClicked, this, &OFControls::setColor);
  connect(xSlider, &QSlider::valueChanged, this, &OFControls::setXLocation);
  connect(ySlider, &QSlider::valueChanged, this, &OFControls::setYLocation);
  connect(zSlider, &QSlider::valueChanged, this, &OFControls::setZLocation);

  // Setup WindowProxy frame and views
  OpenFrames::FrameManager *frameManager = new OpenFrames::FrameManager();
  frameManager->setFrame(_root);
  _windowProxy->setScene(frameManager, 0U, 0U);
  _windowProxy->getGridPosition(0U, 0U)->addView(new OpenFrames::View(_root, _root, OpenFrames::View::ABSOLUTE_FRAME));
  OpenFrames::FollowingTrackball *trackball = _windowProxy->getGridPosition(0U, 0U)->getCurrentView()->getTrackball();
  trackball->setDistance(8.0);
  _windowProxy->getGridPosition(0U, 0U)->getCurrentView()->setTrackball(trackball);
}

OFControls::~OFControls()
{
  // Nothing to do here
}

int OFControls::main(int argc, char **argv)
{
  // Run OpenFrames
  OpenFrames::FramerateLimiter waitLimiter;
  waitLimiter.setDesiredFramerate(1000.0/MAIN_LOOP_PERIOD); // FPS at which to check events

  _windowProxy->start();
  while (_windowProxy->isRunning())
  {
    // check events periodically
    QCoreApplication::processEvents(QEventLoop::AllEvents, MAIN_LOOP_PERIOD);
    waitLimiter.frame();
  }

  return 0;
}

void OFControls::toggleSphere(bool checked)
{
  _windowProxy->getGridPosition(0U, 0U)->getFrameManager()->lock();
  if (_root->getChildIndex(_sphere) >= 0)
  {
    _checkBox->setChecked(false);
    _toggleButton->setText("Show Sphere");
    _root->removeChild(_sphere);
  }
  else
  {
    _checkBox->setChecked(true);
    _toggleButton->setText("Hide Sphere");
    _root->addChild(_sphere);
  }
  _windowProxy->getGridPosition(0U, 0U)->getFrameManager()->unlock();
}

void OFControls::setColor(QListWidgetItem *item)
{
  _sphere->setColor(COLORS.at(item->text().toStdString()));
}

void OFControls::toggleHiddenPanel(bool checked)
{
  _windowProxy->getGridPosition(0U, 0U)->getFrameManager()->lock();
  if (_root->getChildIndex(_hiddenPanel) >= 0)
  {
    _root->removeChild(_hiddenPanel);
  }
  else
  {
    _root->addChild(_hiddenPanel);
  }
  _windowProxy->getGridPosition(0U, 0U)->getFrameManager()->unlock();
}

void OFControls::setXLocation(int position)
{
  osg::Vec3d spherePosition;
  _sphere->getPosition(spherePosition);
  spherePosition[0] = static_cast<double>(position) * 0.1 - 1.55;
  _sphere->setPosition(spherePosition);
}

void OFControls::setYLocation(int position)
{
  osg::Vec3d spherePosition;
  _sphere->getPosition(spherePosition);
  spherePosition[1] = static_cast<double>(position) * 0.1;
  _sphere->setPosition(spherePosition);
}

void OFControls::setZLocation(int position)
{
  osg::Vec3d spherePosition;
  _sphere->getPosition(spherePosition);
  spherePosition[2] = 1.0 + (static_cast<double>(position) * 0.1);
  _sphere->setPosition(spherePosition);
}
<commit_msg>Change QLabel to QTextEdit now that context menus are disabled.<commit_after>/***********************************
Copyright 2017 Ravishankar Mathur

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
***********************************/

#include "ofcontrols.hpp"

#include <OpenFrames/QWidgetPanel.hpp>
#include <OpenFrames/WindowProxy.hpp>
#include <OpenFrames/Sphere.hpp>

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QPushButton>
#include <QCheckBox>
#include <QListWidget>
#include <QSlider>
#include <QScrollbar>

/// The period of event checking in the main loop (milliseconds)
const double OFControls::MAIN_LOOP_PERIOD = 10;

/// Prose for the text edit control
const char *OFControls::LOREM_IPSUM_DOLOR =
  "This is an example of Qt widgets in an OSG texture. The widgets control the sphere sitting above.";

/// Colors for the sphere demo
const std::map<std::string, osg::Vec4> OFControls::COLORS =
  {
    { "Red",{ 1.0, 0.0, 0.0, 0.0 } },
    { "Green",{ 0.0, 0.5, 0.0, 0.0 } },
    { "Blue",{ 0.0, 0.0, 1.0, 0.0 } },
    { "Purple",{ 1.0, 0.0, 1.0, 0.0 } },
    { "Yellow",{ 1.0, 1.0, 0.0, 0.0 } },
    { "Cyan",{ 0.0, 1.0, 1.0, 0.0 } },
    { "Orange",{ 1.0, 0.5, 0.0, 0.0 } },
    { "Navy",{ 0.0, 0.0, 0.5, 0.0 } },
    { "Gray",{ 0.5, 0.5, 0.5, 0.0 } },
};

/// Default color for the sphere
const char *OFControls::DEFAULT_SPHERE_COLOR = COLORS.begin()->first.c_str();

int main(int argc, char **argv)
{
  // Qt requires that we construct the global QApplication before creating any widgets.
  QApplication app(argc, argv);

  // Configure the default appearance for our VR world
  QFont font = app.font();
  font.setPixelSize(20);
  app.setFont(font);

  // Start main app
  static OFControls controls;
  controls.main(argc, argv);
}

OFControls::OFControls()
{
  // Instantiate and configure OpenFrames objects
  _windowProxy = new OpenFrames::WindowProxy(100, 100, 640, 480, 1, 1, false, false);

  _root = new OpenFrames::ReferenceFrame("root");
  _root->showNameLabel(false);
  _root->showAxes(0U);
  _root->showAxesLabels(0U);

  OpenFrames::QWidgetPanel *panel1 = new OpenFrames::QWidgetPanel("panel");
  panel1->setColor(0.8, 0.8, 0.8, 0.9);
  panel1->setHalfLengths(1.5, 1.2, 0.1);
  panel1->setAttitude(-0.707106781186547, 0.0, 0.0, 0.707106781186547);
  panel1->setPosition(0.0, 0.0, -1.0);
  panel1->showAxes(0U);
  panel1->showAxesLabels(0U);
  panel1->setPixelsPerUnit(100.0);
  _root->addChild(panel1);

  OpenFrames::QWidgetPanel *panel2 = new OpenFrames::QWidgetPanel("panel");
  panel2->setColor(0.8, 0.8, 0.8, 0.9);
  panel2->setHalfLengths(1.5, 1.2, 0.1);
  panel2->setPosition(3.1, 0.0, -1.0);
  panel2->setAttitude(-0.707106781186547, 0.0, 0.0, 0.707106781186547);
  panel2->showAxes(0U);
  panel2->showAxesLabels(0U);
  panel2->setPixelsPerUnit(50.0);
  _root->addChild(panel2);

  OpenFrames::QWidgetPanel *panel3 = new OpenFrames::QWidgetPanel("panel");
  panel3->setColor(0.8, 0.8, 0.8, 0.9);
  panel3->setHalfLengths(1.5, 1.2, 0.1);
  panel3->setPosition(-3.1, 0.0, -1.0);
  panel3->setAttitude(-0.707106781186547, 0.0, 0.0, 0.707106781186547);
  panel3->showAxes(0U);
  panel3->showAxesLabels(0U);
  panel3->setPixelsPerUnit(90.0);
  _root->addChild(panel3);

  _hiddenPanel = new OpenFrames::QWidgetPanel("panel");
  _hiddenPanel->setColor(0.8, 0.8, 0.8, 0.8);
  _hiddenPanel->setHalfLengths(1.5, 1.2, 0.1);
  _hiddenPanel->setPosition(3.1, 0.0, 1.5);
  _hiddenPanel->setAttitude(-0.707106781186547, 0.0, 0.0, 0.707106781186547);
  _hiddenPanel->showAxes(0U);
  _hiddenPanel->showAxesLabels(0U);
  _hiddenPanel->setPixelsPerUnit(50.0);

  _sphere = new OpenFrames::Sphere("sphere");
  _sphere->setPosition(-1.55, 0.0, 1.0);
  _sphere->setColor(COLORS.at(DEFAULT_SPHERE_COLOR));
  _sphere->showNameLabel(false);
  _sphere->showAxes(7U);
  _sphere->showAxesLabels(7U);
  _sphere->setRadius(1.0);
  _root->addChild(_sphere);

  // Create the example controls widget
  QWidget *widget1 = new QWidget;
  widget1->setLayout(new QVBoxLayout);
  QString text(LOREM_IPSUM_DOLOR);
  QTextEdit *textEdit = new QTextEdit(text);
  textEdit->setReadOnly(false);
  QPalette palette = textEdit->palette();
  palette.setColor(QPalette::Highlight, Qt::darkBlue);
  palette.setColor(QPalette::HighlightedText, Qt::white);
  textEdit->setPalette(palette);
  widget1->layout()->addWidget(textEdit);
  _toggleButton = new QPushButton("Hide Sphere");
  widget1->layout()->addWidget(_toggleButton);
  panel1->setWidget(widget1);

  // Create the example controls widget
  QWidget *widget2 = new QWidget;
  widget2->setLayout(new QVBoxLayout);
  _checkBox = new QCheckBox("Show sphere");
  _checkBox->setChecked(true);
  QCheckBox *moveSphereBox = new QCheckBox("Move sphere");
  widget2->layout()->addWidget(_checkBox);
  widget2->layout()->addWidget(moveSphereBox);
  panel2->setWidget(widget2);

  // Create the example list view
  QWidget *widget3 = new QWidget;
  widget3->setLayout(new QVBoxLayout);
  _list = new QListWidget();
  _list->setIconSize(QSize(30, 30));
  for (auto color = COLORS.begin(); color != COLORS.end(); color++)
  {
    QListWidgetItem *item = new QListWidgetItem(color->first.c_str());
    const osg::Vec4 &osgColor = color->second;
    QColor qColor(round(osgColor[0]*255.0), round(osgColor[1]*255.0), round(osgColor[2]*255.0));
    QFont font = item->font();
    font.setPixelSize(30);
    item->setFont(font);
    QPixmap pixmap(QSize(30, 30));
    pixmap.fill(qColor);
    item->setIcon(QIcon(pixmap));
    _list->addItem(item);
  }
  QList<QListWidgetItem *> matchingItems = _list->findItems(DEFAULT_SPHERE_COLOR, Qt::MatchExactly);
  if (matchingItems.size() > 0)
  {
    _list->setCurrentItem(matchingItems[0]);
  }
  widget3->layout()->addWidget(_list);
  panel3->setWidget(widget3);

  // Create the example controls widget
  QWidget *widget = new QWidget;
  widget->setLayout(new QVBoxLayout);
  QSlider *xSlider = new QSlider(Qt::Horizontal);
  xSlider->setRange(-20, 20);
  QSlider *ySlider = new QSlider(Qt::Horizontal);
  ySlider->setRange(-20, 20);
  QSlider *zSlider = new QSlider(Qt::Horizontal);
  zSlider->setRange(0, 20);
  widget->layout()->addWidget(xSlider);
  widget->layout()->addWidget(ySlider);
  widget->layout()->addWidget(zSlider);
  _hiddenPanel->setWidget(widget);

  // Connect QObject signals to our slots
  connect(moveSphereBox, &QCheckBox::clicked, this, &OFControls::toggleHiddenPanel);
  connect(_toggleButton, &QPushButton::clicked, this, &OFControls::toggleSphere);
  connect(_checkBox, &QCheckBox::clicked, this, &OFControls::toggleSphere);
  connect(_list, &QListWidget::itemActivated, this, &OFControls::setColor);
  connect(_list, &QListWidget::itemClicked, this, &OFControls::setColor);
  connect(xSlider, &QSlider::valueChanged, this, &OFControls::setXLocation);
  connect(ySlider, &QSlider::valueChanged, this, &OFControls::setYLocation);
  connect(zSlider, &QSlider::valueChanged, this, &OFControls::setZLocation);

  // Setup WindowProxy frame and views
  OpenFrames::FrameManager *frameManager = new OpenFrames::FrameManager();
  frameManager->setFrame(_root);
  _windowProxy->setScene(frameManager, 0U, 0U);
  _windowProxy->getGridPosition(0U, 0U)->addView(new OpenFrames::View(_root, _root, OpenFrames::View::ABSOLUTE_FRAME));
  OpenFrames::FollowingTrackball *trackball = _windowProxy->getGridPosition(0U, 0U)->getCurrentView()->getTrackball();
  trackball->setDistance(8.0);
  _windowProxy->getGridPosition(0U, 0U)->getCurrentView()->setTrackball(trackball);
}

OFControls::~OFControls()
{
  // Nothing to do here
}

int OFControls::main(int argc, char **argv)
{
  // Run OpenFrames
  OpenFrames::FramerateLimiter waitLimiter;
  waitLimiter.setDesiredFramerate(1000.0/MAIN_LOOP_PERIOD); // FPS at which to check events

  _windowProxy->start();
  while (_windowProxy->isRunning())
  {
    // check events periodically
    QCoreApplication::processEvents(QEventLoop::AllEvents, MAIN_LOOP_PERIOD);
    waitLimiter.frame();
  }

  return 0;
}

void OFControls::toggleSphere(bool checked)
{
  _windowProxy->getGridPosition(0U, 0U)->getFrameManager()->lock();
  if (_root->getChildIndex(_sphere) >= 0)
  {
    _checkBox->setChecked(false);
    _toggleButton->setText("Show Sphere");
    _root->removeChild(_sphere);
  }
  else
  {
    _checkBox->setChecked(true);
    _toggleButton->setText("Hide Sphere");
    _root->addChild(_sphere);
  }
  _windowProxy->getGridPosition(0U, 0U)->getFrameManager()->unlock();
}

void OFControls::setColor(QListWidgetItem *item)
{
  _sphere->setColor(COLORS.at(item->text().toStdString()));
}

void OFControls::toggleHiddenPanel(bool checked)
{
  _windowProxy->getGridPosition(0U, 0U)->getFrameManager()->lock();
  if (_root->getChildIndex(_hiddenPanel) >= 0)
  {
    _root->removeChild(_hiddenPanel);
  }
  else
  {
    _root->addChild(_hiddenPanel);
  }
  _windowProxy->getGridPosition(0U, 0U)->getFrameManager()->unlock();
}

void OFControls::setXLocation(int position)
{
  osg::Vec3d spherePosition;
  _sphere->getPosition(spherePosition);
  spherePosition[0] = static_cast<double>(position) * 0.1 - 1.55;
  _sphere->setPosition(spherePosition);
}

void OFControls::setYLocation(int position)
{
  osg::Vec3d spherePosition;
  _sphere->getPosition(spherePosition);
  spherePosition[1] = static_cast<double>(position) * 0.1;
  _sphere->setPosition(spherePosition);
}

void OFControls::setZLocation(int position)
{
  osg::Vec3d spherePosition;
  _sphere->getPosition(spherePosition);
  spherePosition[2] = 1.0 + (static_cast<double>(position) * 0.1);
  _sphere->setPosition(spherePosition);
}
<|endoftext|>


<commit_before>/***********************************************************************
 *    created:    Sun May 25 2014
 *    author:     Timotei Dolean <timotei21@gmail.com>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2014 Paul D Turner & The CEGUI Development Team
 *
 *    Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#include <boost/test/unit_test.hpp>

#include "CEGUI/CEGUI.h"
#include "ItemModelStub.h"

using namespace CEGUI;

//----------------------------------------------------------------------------//
class TestItemViewWindowRenderer : public ItemViewWindowRenderer
{
public:
    TestItemViewWindowRenderer() : ItemViewWindowRenderer("DefaultWindow") { }
    virtual Rectf getViewRenderArea(void) const { return Rectf(0, 0, 0, 0); }
    virtual void resizeViewToContent(bool fit_width, bool fit_height) const { }
    virtual void render() { }
};

//----------------------------------------------------------------------------//
class TestItemView : public ItemView
{
public:
    TestItemView() : ItemView("DefaultWindow", "id0")
    {
        d_windowRenderer = new TestItemViewWindowRenderer();
    }

    ~TestItemView() { delete d_windowRenderer;  }

    virtual ModelIndex indexAt(const Vector2f& position) { return ModelIndex(); }

    virtual void updateScrollbars()
    {
        // do nothing on purpose - we don't want to add all those scrollbars as children
    }

    virtual void resortView() { }
    virtual Rectf getIndexRect(const ModelIndex& index) { return Rectf(0, 0, 0, 0);  }
};

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_SUITE(ItemViewTestSuite)

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_SetsTheModel)
{
    ItemModelStub stub;
    TestItemView testItemView;

    testItemView.setModel(&stub);

    BOOST_CHECK_EQUAL(&stub, testItemView.getModel());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_SameModel_DoesNotSetDirtyState)
{
    ItemModelStub stub;
    TestItemView testItemView;
    testItemView.setModel(&stub);
    testItemView.setIsDirty(false);

    testItemView.setModel(&stub);

    BOOST_CHECK(!testItemView.isDirty());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_DifferentModel_SetsDirtyState)
{
    ItemModelStub stub, stub2;
    TestItemView testItemView;
    testItemView.setModel(&stub);
    testItemView.setIsDirty(false);

    testItemView.setModel(&stub2);

    BOOST_CHECK(testItemView.isDirty());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_ModelHasNewChildren_SetsDirtyState)
{
    ItemModelStub stub;
    TestItemView test_item_view;
    stub.d_items.push_back("item");
    test_item_view.setModel(&stub);

    {
        test_item_view.setIsDirty(false);
        stub.notifyChildrenAdded(stub.getRootIndex(), 0, 1);

        BOOST_CHECK(test_item_view.isDirty());
    }

    {
        test_item_view.setIsDirty(false);
        stub.notifyChildrenRemoved(stub.getRootIndex(), 0, 1);

        BOOST_CHECK(test_item_view.isDirty());
    }
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_DifferentModel_UnhooksPreviousModelEvents)
{
    ItemModelStub stub1, stub2;
    TestItemView test_item_view;
    stub1.d_items.push_back("item");
    test_item_view.setModel(&stub1);

    test_item_view.setModel(&stub2);

    test_item_view.setIsDirty(false);
    stub1.notifyChildrenAdded(stub1.getRootIndex(), 0, 1);

    BOOST_CHECK(!test_item_view.isDirty());
}

BOOST_AUTO_TEST_CASE(ClearSelection)
{
    ItemModelStub stub1;
    TestItemView test_item_view;
    stub1.d_items.push_back("item");
    test_item_view.setModel(&stub1);
    test_item_view.setSelectedItem(stub1.makeIndex(0, stub1.getRootIndex()));

    test_item_view.clearSelections();

    BOOST_REQUIRE_EQUAL(0, test_item_view.getIndexSelectionStates().size());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_DifferentModel_RemovesSelection)
{
    ItemModelStub stub1, stub2;
    TestItemView test_item_view;
    stub1.d_items.push_back("item");
    test_item_view.setModel(&stub1);
    test_item_view.setSelectedItem(stub1.makeIndex(0, stub1.getRootIndex()));

    BOOST_CHECK_EQUAL(1, test_item_view.getIndexSelectionStates().size());

    test_item_view.setModel(&stub2);
    BOOST_REQUIRE_EQUAL(0, test_item_view.getIndexSelectionStates().size());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetSelectedItem_ReplacesSelection)
{
    ItemModelStub stub;
    TestItemView test_item_view;
    stub.d_items.push_back("item1");
    stub.d_items.push_back("item2");
    test_item_view.setModel(&stub);

    test_item_view.setSelectedItem(stub.makeIndex(0, stub.getRootIndex()));
    BOOST_CHECK_EQUAL(1, test_item_view.getIndexSelectionStates().size());

    test_item_view.setSelectedItem(stub.makeIndex(1, stub.getRootIndex()));
    BOOST_REQUIRE_EQUAL(1, test_item_view.getIndexSelectionStates().size());
    BOOST_REQUIRE_EQUAL("item2",
        *(static_cast<String*>(
            test_item_view.getIndexSelectionStates().at(0).d_selectedIndex.d_modelData)));
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetItemSelectionState_MultiSelectToggled_ModifiesSelectionAccordingly)
{
    ItemModelStub stub;
    TestItemView test_item_view;
    stub.d_items.push_back("item1");
    stub.d_items.push_back("item2");
    test_item_view.setModel(&stub);
    test_item_view.setMultiSelectEnabled(true);

    test_item_view.setItemSelectionState(stub.makeIndex(0, stub.getRootIndex()), true);
    test_item_view.setItemSelectionState(stub.makeIndex(1, stub.getRootIndex()), true);

    BOOST_REQUIRE_EQUAL(2, test_item_view.getIndexSelectionStates().size());
    BOOST_REQUIRE_EQUAL("item2",
        *(static_cast<String*>(
            test_item_view.getIndexSelectionStates().at(1).d_selectedIndex.d_modelData)));

    test_item_view.setMultiSelectEnabled(false);
    BOOST_REQUIRE_EQUAL(1, test_item_view.getIndexSelectionStates().size());
    BOOST_REQUIRE_EQUAL("item1",
        *(static_cast<String*>(
            test_item_view.getIndexSelectionStates().at(0).d_selectedIndex.d_modelData)));
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Introduce test fixture for ItemView tests<commit_after>/***********************************************************************
 *    created:    Sun May 25 2014
 *    author:     Timotei Dolean <timotei21@gmail.com>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2014 Paul D Turner & The CEGUI Development Team
 *
 *    Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#include <boost/test/unit_test.hpp>

#include "CEGUI/CEGUI.h"
#include "ItemModelStub.h"

using namespace CEGUI;

//----------------------------------------------------------------------------//
struct ItemViewFixture
{
    ItemViewFixture()
    {
        view = static_cast<ListView*>(WindowManager::getSingleton().createWindow("TaharezLook/ListView", "lv"));
        view->setWindowRenderer("Core/ListView");
        view->setModel(&model);
    }

    ItemModelStub model;
    ItemView* view;
};

BOOST_FIXTURE_TEST_SUITE(ItemViewTestSuite, ItemViewFixture)

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_SetsTheModel)
{
    BOOST_CHECK_EQUAL(&model, view->getModel());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_SameModel_DoesNotSetDirtyState)
{
    view->setIsDirty(false);

    view->setModel(&model);

    BOOST_CHECK(!view->isDirty());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_DifferentModel_SetsDirtyState)
{
    ItemModelStub model2;
    view->setIsDirty(false);

    view->setModel(&model2);

    BOOST_CHECK(view->isDirty());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_ModelHasNewChildren_SetsDirtyState)
{
    model.d_items.push_back("item");

    {
        view->setIsDirty(false);
        model.notifyChildrenAdded(model.getRootIndex(), 0, 1);

        BOOST_CHECK(view->isDirty());
    }

    {
        view->setIsDirty(false);
        model.notifyChildrenRemoved(model.getRootIndex(), 0, 1);

        BOOST_CHECK(view->isDirty());
    }
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_DifferentModel_UnhooksPreviousModelEvents)
{
    model.d_items.push_back("item");

    ItemModelStub model2;
    view->setModel(&model2);

    view->setIsDirty(false);
    model.notifyChildrenAdded(model.getRootIndex(), 0, 1);

    BOOST_CHECK(!view->isDirty());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetModel_DifferentModel_RemovesSelection)
{
    model.d_items.push_back("item");
    view->setSelectedItem(model.makeIndex(0, model.getRootIndex()));

    BOOST_CHECK_EQUAL(1, view->getIndexSelectionStates().size());

    ItemModelStub model2;
    view->setModel(&model2);
    BOOST_REQUIRE_EQUAL(0, view->getIndexSelectionStates().size());
}

BOOST_AUTO_TEST_CASE(ClearSelection)
{
    model.d_items.push_back("item");

    view->setSelectedItem(model.makeIndex(0, model.getRootIndex()));

    view->clearSelections();

    BOOST_REQUIRE_EQUAL(0, view->getIndexSelectionStates().size());
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetSelectedItem_ReplacesSelection)
{
    ItemModelStub stub;
    model.d_items.push_back("item1");
    model.d_items.push_back("item2");
    view->setModel(&model);

    view->setSelectedItem(model.makeIndex(0, model.getRootIndex()));
    BOOST_CHECK_EQUAL(1, view->getIndexSelectionStates().size());

    view->setSelectedItem(model.makeIndex(1, model.getRootIndex()));
    BOOST_REQUIRE_EQUAL(1, view->getIndexSelectionStates().size());
    BOOST_REQUIRE_EQUAL("item2",
        *(static_cast<String*>(
            view->getIndexSelectionStates().at(0).d_selectedIndex.d_modelData)));
}

//----------------------------------------------------------------------------//
BOOST_AUTO_TEST_CASE(SetItemSelectionState_MultiSelectToggled_ModifiesSelectionAccordingly)
{
    ItemModelStub stub;
    model.d_items.push_back("item1");
    model.d_items.push_back("item2");
    view->setModel(&model);
    view->setMultiSelectEnabled(true);

    view->setItemSelectionState(model.makeIndex(0, model.getRootIndex()), true);
    view->setItemSelectionState(model.makeIndex(1, model.getRootIndex()), true);

    BOOST_REQUIRE_EQUAL(2, view->getIndexSelectionStates().size());
    BOOST_REQUIRE_EQUAL("item2",
        *(static_cast<String*>(
            view->getIndexSelectionStates().at(1).d_selectedIndex.d_modelData)));

    view->setMultiSelectEnabled(false);
    BOOST_REQUIRE_EQUAL(1, view->getIndexSelectionStates().size());
    BOOST_REQUIRE_EQUAL("item1",
        *(static_cast<String*>(
            view->getIndexSelectionStates().at(0).d_selectedIndex.d_modelData)));
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "main.hpp"

#include "ImageProvider.hpp"
#include "Resources.hpp"

static const char *face_cascade_xml = "haarcascade_frontalface_alt.xml";
static const char *eyes_cascade_xml = "haarcascade_eye_tree_eyeglasses.xml";

static cv::Size getFrameSize(cv::VideoCapture &capture) {
#if CV_VERSION_EPOCH < 3
  int w = capture.get(CV_CAP_PROP_FRAME_WIDTH);
  int h = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
#else
  int w = capture.get(cv::CAP_PROP_FRAME_WIDTH);
  int h = capture.get(cv::CAP_PROP_FRAME_HEIGHT);
#endif
  return {w, h};
}

bool ImageProvider::create(Resources *resources) {
  face_cascade.load(resources->resolve(face_cascade_xml));
  (void)eyes_cascade_xml; // fix unused variable warning
  return true;
}

bool ImageProvider::start() {
  capture.open(0);
  if (capture.isOpened()) {
    webcam_size = getFrameSize(capture);
    if (webcam_size.width > 0 && webcam_size.height > 0) {
      for(size_t i=0u; i<data.size; ++i) {
        data.getBuffer(i).webcam_pixels = cv::Mat::zeros(webcam_size.height, webcam_size.width, CV_8UC3);
      }

      webcam_thread = std::thread([this] { this->webcamThreadFunc(); });

      return true;
    }
  }
  SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not open webcam",
                           "Could not open webcam", NULL);
  return false;
}
void ImageProvider::stop() {
  if(webcam_thread.joinable()) {
    kill_threads = true;
    webcam_thread.join();
  }

  capture.release();
}

void ImageProvider::webcamThreadFunc() {
  while(!kill_threads) {
    auto assigned = data.startWrite();

    auto &frame = assigned->webcam_pixels;
    auto &faces = assigned->faces;

    if (!capture.isOpened()) {
      return;
    }
    if (!capture.read(frame)) {
      return;
    }
#ifndef NDEBUG
    {
      auto S = getFrameSize(capture);
      assert(static_cast<int>(S.width) == frame.cols &&
             static_cast<int>(S.height) == frame.rows);
    }
#endif

    cv::Mat frame_gray;

    cv::cvtColor(frame, frame_gray, CV_BGR2GRAY);
    cv::equalizeHist(frame_gray, frame_gray);
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2,
                                  0 | CV_HAAR_SCALE_IMAGE, cv::Size(30, 30));

    data.finishWrite();
  }
}
<commit_msg>Add #ifdef'ed out face detection debug draw<commit_after>#include "main.hpp"

#include "ImageProvider.hpp"
#include "Resources.hpp"

static const char *face_cascade_xml = "haarcascade_frontalface_alt.xml";
static const char *eyes_cascade_xml = "haarcascade_eye_tree_eyeglasses.xml";

static cv::Size getFrameSize(cv::VideoCapture &capture) {
#if CV_VERSION_EPOCH < 3
  int w = capture.get(CV_CAP_PROP_FRAME_WIDTH);
  int h = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
#else
  int w = capture.get(cv::CAP_PROP_FRAME_WIDTH);
  int h = capture.get(cv::CAP_PROP_FRAME_HEIGHT);
#endif
  return {w, h};
}

bool ImageProvider::create(Resources *resources) {
  face_cascade.load(resources->resolve(face_cascade_xml));
  (void)eyes_cascade_xml; // fix unused variable warning
  return true;
}

bool ImageProvider::start() {
  capture.open(0);
  if (capture.isOpened()) {
    webcam_size = getFrameSize(capture);
    if (webcam_size.width > 0 && webcam_size.height > 0) {
      for(size_t i=0u; i<data.size; ++i) {
        data.getBuffer(i).webcam_pixels = cv::Mat::zeros(webcam_size.height, webcam_size.width, CV_8UC3);
      }

      webcam_thread = std::thread([this] { this->webcamThreadFunc(); });

      return true;
    }
  }
  SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not open webcam",
                           "Could not open webcam", NULL);
  return false;
}
void ImageProvider::stop() {
  if(webcam_thread.joinable()) {
    kill_threads = true;
    webcam_thread.join();
  }

  capture.release();
}

void ImageProvider::webcamThreadFunc() {
  while(!kill_threads) {
    auto assigned = data.startWrite();

    auto &frame = assigned->webcam_pixels;
    auto &faces = assigned->faces;

    if (!capture.isOpened()) {
      return;
    }
    if (!capture.read(frame)) {
      return;
    }
#ifndef NDEBUG
    {
      auto S = getFrameSize(capture);
      assert(static_cast<int>(S.width) == frame.cols &&
             static_cast<int>(S.height) == frame.rows);
    }
#endif

    cv::Mat frame_gray;

    cv::cvtColor(frame, frame_gray, CV_BGR2GRAY);
    cv::equalizeHist(frame_gray, frame_gray);
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2,
                                  0 | CV_HAAR_SCALE_IMAGE, cv::Size(30, 30));

#if 0
    for(const auto &f : faces) {
      cv::rectangle(frame, f, cv::Scalar(0, 0, 255));
    }
#endif

    data.finishWrite();
  }
}
<|endoftext|>


<commit_before>#include "common/common.h"
#include "common/random_utils.h"
#include "common/cmd_options.h"

#include "common/graph/dot_graph.h"
#include "common/graph/dot_parser.h"

#include "clustering.h"
#include "metrics.h"

#include <memory>

void PrepareCMDOptions(int argc, char** argv, CMDOptions& args)
{
	string msg;
	msg += "Usage: kmeans [options] input_file\n";
	msg += "When input_file is not supplied, the program reads from stdin.\n";
	args.SetUsageMessage(msg);

	args.AddAllowedOption("", "", "Input file name (stdin, if no input file is supplied)");
	args.AddAllowedOption("-o", "", "Output file name (stdout, if no output file is supplied)");

	args.AddAllowedOption("-action", "The program either computes a clustering for a given graph or calculates a set of quality measures (aesthetics)");
	args.AddAllowedValue("-action", "clustering");
	args.AddAllowedValue("-action", "metrics");

	args.AddAllowedOption("-C", "Type of clustering");
	args.AddAllowedValue("-C", "geometrickmeans");
	args.AddAllowedValue("-C", "graphkmeans");
	args.AddAllowedValue("-C", "geometrichierarchical");
	args.AddAllowedValue("-C", "graphhierarchical");
	args.AddAllowedValue("-C", "infomap");
	args.AddAllowedValue("-C", "modularity");
	args.AddAllowedValue("-C", "modularity-cont");

	args.AddAllowedOption("-K", "", "Desired number of clusters (selected automatically, if no value is supplied)");

	args.Parse(argc, argv);
}

void MetricsAction(const CMDOptions& options)
{
	DotReader parser;
	DotGraph g = parser.ReadGraph(options.getOption(""));

	Metrics m;
	m.Compute(g);
	m.Output(options.getOption("-o"));
}

void ClusteringAction(const CMDOptions& options)
{
	DotReader parser;
	DotGraph g = parser.ReadGraph(options.getOption(""));

	string algoName = options.getOption("-C");
	ClusterAlgorithm* algo = NULL;

	if (algoName == "geometrickmeans")
		algo = new GeometricKMeans();
	else if (algoName == "graphkmeans")
		algo = new GraphKMeans();
	else if (algoName == "geometrichierarchical")
		algo = new GeometricHierarchical();
	else if (algoName == "graphhierarchical")
		algo = new GraphHierarchical();
	else if (algoName == "infomap")
		algo = new InfoMap();
	else if (algoName == "modularity")
		algo = new Modularity(false);
	else if (algoName == "modularity-cont")
		algo = new Modularity(true);

	string numberOfClusters = options.getOption("-K");
	if (numberOfClusters == "graph")
	{
		int k = g.ClusterCount();
		algo->cluster(g, k);
	}
	else if (numberOfClusters == "")
	{
		algo->cluster(g);
	}
	else
	{
		int k = toInt(numberOfClusters);
		algo->cluster(g, k);
	}

	delete algo;

	DotWriter writer;
	writer.WriteGraph(options.getOption("-o"), g);
}

int main(int argc, char **argv)
{
	InitRand(123);

	auto options = CMDOptions::Create();

	int returnCode = 0;
	try
	{
		PrepareCMDOptions(argc, argv, *options);
		string action = options->getOption("-action");
		if (action == "clustering")
		{
			ClusteringAction(*options);
		}
		else if (action == "metrics")
		{
			MetricsAction(*options);
		}
	}
	catch (int code)
	{
		returnCode = code;
	}

	return returnCode;
}
<commit_msg>small fix<commit_after>#include "common/common.h"
#include "common/random_utils.h"
#include "common/cmd_options.h"

#include "common/graph/dot_graph.h"
#include "common/graph/dot_parser.h"

#include "clustering.h"
#include "metrics.h"

#include <memory>

void PrepareCMDOptions(int argc, char** argv, CMDOptions& args)
{
	string msg;
	msg += "Usage: kmeans [options] input_file\n";
	msg += "When input_file is not supplied, the program reads from stdin.\n";
	args.SetUsageMessage(msg);

	args.AddAllowedOption("", "", "Input file name (stdin, if no input file is supplied)");
	args.AddAllowedOption("-o", "", "Output file name (stdout, if no output file is supplied)");

	args.AddAllowedOption("-action", "The program either computes a clustering for a given graph or calculates a set of quality measures (aesthetics)");
	args.AddAllowedValue("-action", "clustering");
	args.AddAllowedValue("-action", "metrics");

	args.AddAllowedOption("-C", "Type of clustering");
	args.AddAllowedValue("-C", "geometrickmeans");
	args.AddAllowedValue("-C", "graphkmeans");
	args.AddAllowedValue("-C", "geometrichierarchical");
	args.AddAllowedValue("-C", "graphhierarchical");
	args.AddAllowedValue("-C", "infomap");
	args.AddAllowedValue("-C", "modularity");
	args.AddAllowedValue("-C", "modularity-cont");

	args.AddAllowedOption("-K", "", "Desired number of clusters (selected automatically, if no value is supplied)");

	args.Parse(argc, argv);
}

void MetricsAction(const CMDOptions& options)
{
	DotReader parser;
	DotGraph g = parser.ReadGraph(options.getOption(""));

	Metrics m;
	m.Compute(g);
	m.Output(options.getOption("-o"));
}

void ClusteringAction(const CMDOptions& options)
{
	DotReader parser;
	DotGraph g = parser.ReadGraph(options.getOption(""));

	string algoName = options.getOption("-C");
	ClusterAlgorithm* algo = NULL;

	if (algoName == "geometrickmeans")
		algo = new GeometricKMeans();
	else if (algoName == "graphkmeans")
		algo = new GraphKMeans();
	else if (algoName == "geometrichierarchical")
		algo = new GeometricHierarchical();
	else if (algoName == "graphhierarchical")
		algo = new GraphHierarchical();
	else if (algoName == "infomap")
		algo = new InfoMap();
	else if (algoName == "modularity")
		algo = new Modularity(false);
	else if (algoName == "modularity-cont")
		algo = new Modularity(true);

	string numberOfClusters = options.getOption("-K");
	if (numberOfClusters == "graph")
	{
		int k = g.ClusterCount();
		algo->cluster(g, k);
	}
	else if (numberOfClusters == "")
	{
		algo->cluster(g);
	}
	else
	{
		int k = toInt(numberOfClusters);
		algo->cluster(g, k);
	}

	delete algo;

	DotWriter writer;
	writer.WriteGraph(options.getOption("-o"), g);
}

int main(int argc, char **argv)
{
	InitRand(123);

	auto options = CMDOptions::Create();

	int returnCode = 0;
	try
	{
		PrepareCMDOptions(argc, argv, *options);
		string action = options->getOption("-action");
		if (action == "clustering")
		{
			ClusteringAction(*options);
		}
		else if (action == "metrics")
		{
			MetricsAction(*options);
		}
	}
	catch (int code)
	{
		returnCode = code;
	}

	return returnCode;
}
<|endoftext|>


<commit_before>#include "scene/Scene.h"

namespace epsilon
{
	Scene::Ptr Scene::Create(std::string name)
	{
		Scene::Ptr newScene = std::make_shared<Scene>(private_struct(), name);
		newScene->Setup();
		return newScene;
	}

	Scene::Scene(const private_struct &, std::string sceneName) : name(sceneName)
	{
	}

	Scene::~Scene(void)
	{
		if ( rootNode != NULL )
		{
			rootNode->OnDestroy();
		}
	}

	// Initialise the default values of the scene
	void Scene::Setup()
	{
		// Create a root node for the scene
		rootNode = SceneNode::Create("root");

		// Set the this scene as the current scene
		rootNode->SetScene(ThisPtr());

		// Get the new node's transform as the scene root transform
		rootTransform = rootNode->GetTransform();

		// Attach a node with a camera as the default scene camera
		SceneNode::Ptr camNode = rootNode->CreateChild("camera_node");

		// Set the new camera as the default / active camera
		SetActiveCamera(camNode->CreateCamera("main_camera"));
	}

	bool Scene::operator==(Scene::Ptr other)
	{
		return name == other->name;
	}

	bool Scene::operator==(std::string otherName)
	{
		return name == otherName;
	}

	void Scene::Update(float el)
	{
		rootTransform->_update(true, false);
	}

	void Scene::SetActiveCamera(Camera::Ptr camera)
	{
		// Add the camera
		AddCamera(camera);

		// Set it as the active camera
		activeCamera = camera;
	}

	void Scene::SetActiveCamera(std::string name)
	{
		// Find the camera
		bool found = false;

		for ( CameraList::iterator cam = sceneCameras.begin(); cam != sceneCameras.end(); cam++ )
		{
			if ( (*cam)->GetName() == name )
			{
				// Set it as the active camera
				activeCamera = (*cam);
				found = true;
				break;
			}
		}

		// if a new camera
		if (!found)
		{
			Log(Format("Error setting active camera.  Unknown camera: %s", name.c_str()));
		}
	}

	bool Scene::AddCamera(Camera::Ptr newCamera)
	{
		// Find the camera
		bool found = false;

		for ( CameraList::iterator cam = sceneCameras.begin(); cam != sceneCameras.end(); cam++ )
		{
			if ( newCamera->GetId() == (*cam)->GetId() )
			{
				found = true;
				break;
			}
		}

		// if a new camera
		if (!found)
		{
			// keep track of it
			sceneCameras.push_back(newCamera);
		}

		// Return the result of the add
		return !found;
	}

	Camera::Ptr Scene::GetCamera(std::string name)
	{
		Camera::Ptr foundCam;

		for ( CameraList::iterator cam = sceneCameras.begin(); cam != sceneCameras.end(); cam++ )
		{
			if ( (*cam)->GetName() == name )
			{
				// Set it as the active camera
				foundCam = (*cam);
				break;
			}
		}

		return foundCam;
	}

	bool Scene::AddLight(Light::Ptr light)
	{
		bool success = false;

		LightList::iterator it = std::find_if(sceneLights.begin(), sceneLights.end(), [&](Light::Ptr light){
			return light->GetName() == name;
		});

		if (it != sceneLights.end())
		{
			sceneLights.push_back(light);
			success = true;
		}

		return success;
	}

	Light::Ptr Scene::GetLight(std::string name)
	{
		Light::Ptr foundLight;

		LightList::iterator it = std::find_if(sceneLights.begin(), sceneLights.end(), [&](Light::Ptr light){
			return light->GetName() == name;
		});

		if (it != sceneLights.end())
		{
			foundLight = *it;
		}

		return foundLight;
	}

}
<commit_msg>M Set a better position for the default scene camera.<commit_after>#include "scene/Scene.h"

namespace epsilon
{
	Scene::Ptr Scene::Create(std::string name)
	{
		Scene::Ptr newScene = std::make_shared<Scene>(private_struct(), name);
		newScene->Setup();
		return newScene;
	}

	Scene::Scene(const private_struct &, std::string sceneName) : name(sceneName)
	{
	}

	Scene::~Scene(void)
	{
		if ( rootNode != NULL )
		{
			rootNode->OnDestroy();
		}
	}

	// Initialise the default values of the scene
	void Scene::Setup()
	{
		// Create a root node for the scene
		rootNode = SceneNode::Create("root");

		// Set the this scene as the current scene
		rootNode->SetScene(ThisPtr());

		// Get the new node's transform as the scene root transform
		rootTransform = rootNode->GetTransform();

		// Attach a node with a camera as the default scene camera
		SceneNode::Ptr camNode = rootNode->CreateChild("camera_node");

		// Set the new camera as the default / active camera
		SetActiveCamera(camNode->CreateCamera("main_camera"));

		// Move default camera to a suitable position
		camNode->transform->SetPosition(0, 1, -10);

		//camNode->transform->LookAt(Vector3(0, 1, 0));
	}

	bool Scene::operator==(Scene::Ptr other)
	{
		return name == other->name;
	}

	bool Scene::operator==(std::string otherName)
	{
		return name == otherName;
	}

	void Scene::Update(float el)
	{
		rootTransform->_update(true, false);
	}

	void Scene::SetActiveCamera(Camera::Ptr camera)
	{
		// Add the camera
		AddCamera(camera);

		// Set it as the active camera
		activeCamera = camera;
	}

	void Scene::SetActiveCamera(std::string name)
	{
		// Find the camera
		bool found = false;

		for ( CameraList::iterator cam = sceneCameras.begin(); cam != sceneCameras.end(); cam++ )
		{
			if ( (*cam)->GetName() == name )
			{
				// Set it as the active camera
				activeCamera = (*cam);
				found = true;
				break;
			}
		}

		// if a new camera
		if (!found)
		{
			Log(Format("Error setting active camera.  Unknown camera: %s", name.c_str()));
		}
	}

	bool Scene::AddCamera(Camera::Ptr newCamera)
	{
		// Find the camera
		bool found = false;

		for ( CameraList::iterator cam = sceneCameras.begin(); cam != sceneCameras.end(); cam++ )
		{
			if ( newCamera->GetId() == (*cam)->GetId() )
			{
				found = true;
				break;
			}
		}

		// if a new camera
		if (!found)
		{
			// keep track of it
			sceneCameras.push_back(newCamera);
		}

		// Return the result of the add
		return !found;
	}

	Camera::Ptr Scene::GetCamera(std::string name)
	{
		Camera::Ptr foundCam;

		for ( CameraList::iterator cam = sceneCameras.begin(); cam != sceneCameras.end(); cam++ )
		{
			if ( (*cam)->GetName() == name )
			{
				// Set it as the active camera
				foundCam = (*cam);
				break;
			}
		}

		return foundCam;
	}

	bool Scene::AddLight(Light::Ptr light)
	{
		bool success = false;

		LightList::iterator it = std::find_if(sceneLights.begin(), sceneLights.end(), [&](Light::Ptr light){
			return light->GetName() == name;
		});

		if (it != sceneLights.end())
		{
			sceneLights.push_back(light);
			success = true;
		}

		return success;
	}

	Light::Ptr Scene::GetLight(std::string name)
	{
		Light::Ptr foundLight;

		LightList::iterator it = std::find_if(sceneLights.begin(), sceneLights.end(), [&](Light::Ptr light){
			return light->GetName() == name;
		});

		if (it != sceneLights.end())
		{
			foundLight = *it;
		}

		return foundLight;
	}

}
<|endoftext|>


<commit_before>// ------------------------------------------------------------------------------------------------
#include "Library/Utils.hpp"

// ------------------------------------------------------------------------------------------------
namespace SqMod {

// ------------------------------------------------------------------------------------------------
extern void Register_Buffer(HSQUIRRELVM vm);

// ================================================================================================
void Register_Utils(HSQUIRRELVM vm)
{
    Register_Buffer(vm);
}

} // Namespace:: SqMod
<commit_msg>Implement a simple utility method to extract the components of an IPv4 address.<commit_after>// ------------------------------------------------------------------------------------------------
#include "Library/Utils.hpp"

// ------------------------------------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>

// ------------------------------------------------------------------------------------------------
namespace SqMod {

// ------------------------------------------------------------------------------------------------
extern void Register_Buffer(HSQUIRRELVM vm);

/* ------------------------------------------------------------------------------------------------
 * Probably not the best implementation but should cover all sorts of weird cases.
*/
static SQInteger SqExtractIPv4(HSQUIRRELVM vm)
{
    // Was the IP address specified?
    if (sq_gettop(vm) <= 1)
    {
        return sq_throwerror(vm, "Missing IP address string");
    }
    // Attempt to generate the string value
    StackStrF val(vm, 2);
    // Have we failed to retrieve the string?
    if (SQ_FAILED(val.mRes))
    {
        return val.mRes; // Propagate the error!
    }
    // Cleansed IP address buffer
    SQChar address[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    // Counting variables used by loops
    Uint32 i = 0, j = 0, k = 0;
    // Replicate the necessary characters from the resulted string
    for (; (i < static_cast< Uint32 >(val.mLen)) && (j < 16) && (k < 4); ++i)
    {
        // Is this a digit?
        if (std::isdigit(val.mPtr[i]) != 0)
        {
            address[j++] = val.mPtr[i]; // Just replicate it
        }
        // Is this a delimiter?
        else if (val.mPtr[i] == '.')
        {
            // Add a dummy component if one was not specified
            if (j == 0 || address[j-1] == '.')
            {
                address[j++] = '0';
            }
            // Add the actual delimiter
            address[j++] = '.';
            // Increase the block counter
            ++k;
        }
    }
    // Complete the address if it wasn't (also count the last block)
    while (++k < 4)
    {
        address[j++] = '0';
        address[j++] = '.';
    }
    // Components of the IP address
    Uint32 blocks[4] = {0, 0, 0, 0};
    // Attempt to extract the components of the IP address
    std::sscanf(address, "%u.%u.%u.%u", &blocks[0], &blocks[1], &blocks[2], &blocks[3]);
    // Create a new array on the stack to hold the extracted components
    sq_newarray(vm, 4);
    // Push the elements into the array
    for (i = 0; i < 4; ++i)
    {
        // Push the element index
        sq_pushinteger(vm, i);
        // Push the element value
        sq_pushinteger(vm, Clamp(blocks[i], 0U, 255U));
        // Assign the element
        const SQRESULT res = sq_set(vm, -3);
        // See if the assignment failed
        if (SQ_FAILED(res))
        {
            return res;
        }
    }
    // Specify that we have a result on the stack
    return 1;
}

// ================================================================================================
void Register_Utils(HSQUIRRELVM vm)
{
    RootTable(vm).Bind(_SC("SqUtils"), Table(vm)
        .SquirrelFunc(_SC("ExtractIPv4"), &SqExtractIPv4)
    );

    Register_Buffer(vm);
}

} // Namespace:: SqMod
<|endoftext|>