<commit_before>/** Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Roland Olbricht et al.
 *
 * This file is part of Overpass_API.
 *
 * Overpass_API is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Overpass_API 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 Affero General Public License
 * along with Overpass_API.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "lz4_wrapper.h"

#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdexcept>

namespace
{
  template < typename T >
  std::string to_string(T t)
  {
    std::ostringstream out;
    out<<std::setprecision(14)<<t;
    return out.str();
  }
}

LZ4_Deflate::Error::Error(int error_code_)
    : std::runtime_error("LZ4_Deflate: " + to_string(error_code_)), error_code(error_code_)
{}

LZ4_Deflate::LZ4_Deflate() { }

LZ4_Deflate::~LZ4_Deflate() { }

int LZ4_Deflate::compress(const void* in, int in_size, void* out, int out_buffer_size)
{
#ifdef HAVE_LZ4

   int ret = LZ4_compress_limitedOutput((const char*) in, (char *) out + 4, in_size, out_buffer_size - 4);

   if (ret == 0 || ret > in_size)
   { // compression failed, or result size increased during compression
     if (in_size > out_buffer_size - 4)
       throw std::runtime_error("LZ4: output buffer too small during compression");

     *(int*)out = in_size * -1;
     std::memcpy ((char *) out + 4, (const char*)in, in_size);
     ret = in_size;
   }
   else
     *(int*)out = ret;

   return ret + 4;

#else

  throw std::runtime_error("Overpass API was compiled without lz4 compression library support");

#endif
}

LZ4_Inflate::Error::Error(int error_code_)
    : std::runtime_error("LZ4_Inflate: " + to_string(error_code_)), error_code(error_code_)
{}

LZ4_Inflate::LZ4_Inflate() { }

LZ4_Inflate::~LZ4_Inflate() { }

int LZ4_Inflate::decompress(const void* in, int in_size, void* out, int out_buffer_size)
{
#ifdef HAVE_LZ4

  int ret;
  int in_buffer_size = *(int*)in;

  if (in_buffer_size > 0)
  {
    ret = LZ4_decompress_safe((const char*) in + 4, (char*) out, in_buffer_size, out_buffer_size);
    if (ret < 0)
      throw std::runtime_error("LZ4_decompress_safe failed");
  }
  else
  {
    in_buffer_size *= -1;
    if (in_buffer_size > out_buffer_size)
      throw std::runtime_error ("LZ4: output buffer too small during decompression");

    std::memcpy ((char*) out, (const char*) in + 4, in_buffer_size);
    ret = in_buffer_size;
  }
  return ret;

#else

  throw std::runtime_error("Overpass API was compiled without lz4 compression library support");

#endif
}
<commit_msg>Use LZ4_compress_default to avoid deprecation warning<commit_after>/** Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Roland Olbricht et al.
 *
 * This file is part of Overpass_API.
 *
 * Overpass_API is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Overpass_API 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 Affero General Public License
 * along with Overpass_API.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "lz4_wrapper.h"

#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdexcept>

namespace
{
  template < typename T >
  std::string to_string(T t)
  {
    std::ostringstream out;
    out<<std::setprecision(14)<<t;
    return out.str();
  }
}

LZ4_Deflate::Error::Error(int error_code_)
    : std::runtime_error("LZ4_Deflate: " + to_string(error_code_)), error_code(error_code_)
{}

LZ4_Deflate::LZ4_Deflate() { }

LZ4_Deflate::~LZ4_Deflate() { }

int LZ4_Deflate::compress(const void* in, int in_size, void* out, int out_buffer_size)
{
#ifdef HAVE_LZ4

   int ret = LZ4_compress_default((const char*) in, (char *) out + 4, in_size, out_buffer_size - 4);

   if (ret == 0 || ret > in_size)
   { // compression failed, or result size increased during compression
     if (in_size > out_buffer_size - 4)
       throw std::runtime_error("LZ4: output buffer too small during compression");

     *(int*)out = in_size * -1;
     std::memcpy ((char *) out + 4, (const char*)in, in_size);
     ret = in_size;
   }
   else
     *(int*)out = ret;

   return ret + 4;

#else

  throw std::runtime_error("Overpass API was compiled without lz4 compression library support");

#endif
}

LZ4_Inflate::Error::Error(int error_code_)
    : std::runtime_error("LZ4_Inflate: " + to_string(error_code_)), error_code(error_code_)
{}

LZ4_Inflate::LZ4_Inflate() { }

LZ4_Inflate::~LZ4_Inflate() { }

int LZ4_Inflate::decompress(const void* in, int in_size, void* out, int out_buffer_size)
{
#ifdef HAVE_LZ4

  int ret;
  int in_buffer_size = *(int*)in;

  if (in_buffer_size > 0)
  {
    ret = LZ4_decompress_safe((const char*) in + 4, (char*) out, in_buffer_size, out_buffer_size);
    if (ret < 0)
      throw std::runtime_error("LZ4_decompress_safe failed");
  }
  else
  {
    in_buffer_size *= -1;
    if (in_buffer_size > out_buffer_size)
      throw std::runtime_error ("LZ4: output buffer too small during decompression");

    std::memcpy ((char*) out, (const char*) in + 4, in_buffer_size);
    ret = in_buffer_size;
  }
  return ret;

#else

  throw std::runtime_error("Overpass API was compiled without lz4 compression library support");

#endif
}
<|endoftext|>


<commit_before><commit_msg>EXTRA THREEDEEE<commit_after><|endoftext|>


<commit_before><commit_msg>jibby<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ScrollView.h"

#include "Scrollbar.h"

using std::max;

namespace WebCore {

void ScrollView::init()
{
    m_canBlitOnScroll = true;
    if (platformWidget())
        platformSetCanBlitOnScroll();
}

void ScrollView::addChild(Widget* child)
{
    ASSERT(child != this && !child->parent());
    child->setParent(this);
    m_children.add(child);
    if (!child->platformWidget()) {
        child->setContainingWindow(containingWindow());
        return;
    }
    platformAddChild(child);
}

void ScrollView::removeChild(Widget* child)
{
    ASSERT(child->parent() == this);
    child->setParent(0);
    m_children.remove(child);
    if (child->platformWidget())
        platformRemoveChild(child);
}

void ScrollView::setCanBlitOnScroll(bool b)
{
    if (m_canBlitOnScroll == b)
        return;
    m_canBlitOnScroll = b;
    if (platformWidget())
        platformSetCanBlitOnScroll();
}

IntRect ScrollView::visibleContentRect(bool includeScrollbars) const
{
    if (platformWidget())
        return platformVisibleContentRect(includeScrollbars);
    return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()),
                   IntSize(max(0, width() - (verticalScrollbar() && !includeScrollbars ? verticalScrollbar()->width() : 0)),
                           max(0, height() - (horizontalScrollbar() && !includeScrollbars ? horizontalScrollbar()->height() : 0))));
}

IntSize ScrollView::contentsSize() const
{
    if (platformWidget())
        return platformContentsSize();
    return m_contentsSize;
}

void ScrollView::setContentsSize(const IntSize& newSize)
{
    if (contentsSize() == newSize)
        return;
    m_contentsSize = newSize;
    if (platformWidget())
        platformSetContentsSize();
    else
        updateScrollbars(scrollOffset());
}

IntPoint ScrollView::maximumScrollPosition() const
{
    IntSize maximumOffset = contentsSize() - visibleContentRect().size();
    maximumOffset.clampNegativeToZero();
    return IntPoint(maximumOffset.width(), maximumOffset.height());
}

void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
{
    IntPoint p(max(0, r.x()), max(0, r.y()));
    ScrollView* view = this;
    while (view) {
        view->setScrollPosition(p);
        p.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height());
        view = view->parent();
    }
}

#if !PLATFORM(MAC)
void ScrollView::platformSetCanBlitOnScroll()
{
}
#endif

#if !PLATFORM(MAC) && !PLATFORM(WX)
IntRect ScrollView::platformVisibleContentRect(bool) const
{
    return IntRect();
}

IntSize ScrollView::platformContentsSize() const
{
    return IntSize();
}
#endif

}

<commit_msg>Fix Win, Gtk, Qt bustage.<commit_after>/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ScrollView.h"

#include "Scrollbar.h"

using std::max;

namespace WebCore {

void ScrollView::init()
{
    m_canBlitOnScroll = true;
    if (platformWidget())
        platformSetCanBlitOnScroll();
}

void ScrollView::addChild(Widget* child)
{
    ASSERT(child != this && !child->parent());
    child->setParent(this);
    m_children.add(child);
    if (!child->platformWidget()) {
        child->setContainingWindow(containingWindow());
        return;
    }
    platformAddChild(child);
}

void ScrollView::removeChild(Widget* child)
{
    ASSERT(child->parent() == this);
    child->setParent(0);
    m_children.remove(child);
    if (child->platformWidget())
        platformRemoveChild(child);
}

void ScrollView::setCanBlitOnScroll(bool b)
{
    if (m_canBlitOnScroll == b)
        return;
    m_canBlitOnScroll = b;
    if (platformWidget())
        platformSetCanBlitOnScroll();
}

IntRect ScrollView::visibleContentRect(bool includeScrollbars) const
{
    if (platformWidget())
        return platformVisibleContentRect(includeScrollbars);
    return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()),
                   IntSize(max(0, width() - (verticalScrollbar() && !includeScrollbars ? verticalScrollbar()->width() : 0)),
                           max(0, height() - (horizontalScrollbar() && !includeScrollbars ? horizontalScrollbar()->height() : 0))));
}

IntSize ScrollView::contentsSize() const
{
    if (platformWidget())
        return platformContentsSize();
    return m_contentsSize;
}

void ScrollView::setContentsSize(const IntSize& newSize)
{
    if (contentsSize() == newSize)
        return;
    m_contentsSize = newSize;
    if (platformWidget())
        platformSetContentsSize();
    else
        updateScrollbars(scrollOffset());
}

IntPoint ScrollView::maximumScrollPosition() const
{
    IntSize maximumOffset = contentsSize() - visibleContentRect().size();
    maximumOffset.clampNegativeToZero();
    return IntPoint(maximumOffset.width(), maximumOffset.height());
}

void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
{
    IntPoint p(max(0, r.x()), max(0, r.y()));
    ScrollView* view = this;
    while (view) {
        view->setScrollPosition(p);
        p.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height());
        view = view->parent();
    }
}

#if !PLATFORM(MAC)
void ScrollView::platformSetCanBlitOnScroll()
{
}
#endif

#if !PLATFORM(MAC) && !PLATFORM(WX)
IntRect ScrollView::platformVisibleContentRect(bool) const
{
    return IntRect();
}

IntSize ScrollView::platformContentsSize() const
{
    return IntSize();
}

void ScrollView::platformSetContentsSize()
{
}
#endif

}

<|endoftext|>


<commit_before>// Filename: audio_linux_traits.C
// Created by:  cary (02Oct00)
//
////////////////////////////////////////////////////////////////////

#include "audio_linux_traits.h"

#ifdef AUDIO_USE_LINUX

#include "audio_manager.h"
#include "config_audio.h"
#include <ipc_thread.h>
#include <ipc_mutex.h>
#include <set>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>

typedef set<Buffer*> BufferSet;

static bool have_initialized = false;
static mutex buffer_mutex;
static byte* buffer1;
static byte* buffer2;
static byte* current_buffer;
static byte* back_buffer;
byte* zero_buffer;
static byte* scratch_buffer;
static byte* fetch_buffer;
static int want_buffers = 0, have_buffers = 0;
static bool initializing = true;
static bool stop_mixing = false;
static int output_fd;
static thread* update_thread;
static int sample_size = sizeof(short);

BufferSet buffers;

static void swap_buffers(void) {
  byte *tmp = current_buffer;
  current_buffer = back_buffer;
  back_buffer = tmp;
}

INLINE static signed short read_buffer(byte* buf, int idx) {
  signed short ret = 0;
  switch (sample_size) {
  case 1:
    ret = *((signed char *)(&buf[idx]));
    break;
  case 2:
    ret = *((signed short *)(&buf[idx*2]));
    break;
  default:
    audio_cat->debug() << "unknown sample size (" << sample_size << ")"
		       << endl;
    break;
  }
  return ret;
}

INLINE static void write_buffer(byte* buf, int idx, signed short val) {
  switch (sample_size) {
  case 1:
    *((signed char *)(&buf[idx])) = val & 0xff;
    break;
  case 2:
    *((signed short *)(&buf[idx*2])) = val;
    break;
  default:
    audio_cat->debug() << "unknown sample size (" << sample_size << ")"
		       << endl;
    break;
  }
}

INLINE static signed short sound_clamp(signed int value) {
  signed short ret = 0;
  switch (sample_size) {
  case 1:
    ret = (value > 127)?127:((value < -128)?(-128):(value));
    break;
  case 2:
    ret = (value > 32767)?32767:((value < -32768)?(-32768):(value));
    break;
  default:
    audio_cat->debug() << "unknown sample size (" << sample_size << ")"
		       << endl;
    break;
  }
  return ret;
}

static void mix_in(byte* buf, byte* from, float vol, float pan) {
  int done = audio_buffer_size / sample_size;
  for (int i=0; i<done; i+=2) {
    signed short left = read_buffer(buf, i);
    signed short right = read_buffer(buf, i+1);

    // now get the incoming data
    signed short in_left = read_buffer(from, i);
    signed short in_right = read_buffer(from, i+1);

    // figure out panning at some point
    in_left = (short int)(in_left * vol);
    in_right = (short int)(in_right * vol);

    // compute mixed values
    left = sound_clamp(left+in_left);
    right = sound_clamp(right+in_right);

    // write it back to the buffer
    write_buffer(buf, i, left);
    write_buffer(buf, i+1, right);
  }
}

static void mix_buffer(byte* buf) {
  memcpy(scratch_buffer, zero_buffer, audio_buffer_size);
  // do stuff
  for (BufferSet::iterator i=buffers.begin(); i!=buffers.end(); ++i)
    mix_in(scratch_buffer, (*i)->get_buffer(fetch_buffer), 1., 0.);
  BufferSet to_del;
  for (BufferSet::iterator j=buffers.begin(); j!=buffers.end(); ++j)
    if ((*j)->is_done())
      to_del.insert(*j);
  {
    mutex_lock m(buffer_mutex);
    memcpy(buf, scratch_buffer, audio_buffer_size);
    --want_buffers;
    ++have_buffers;
    for (BufferSet::iterator k=to_del.begin(); k!=to_del.end(); ++k) {
      buffers.erase(*k);
      (*k)->reset();
    }
  }
}

static void update_linux(void) {
  if (buffers.empty())
    return;
  switch (want_buffers) {
  case 0:
    // all buffers are full right now.  This is a good state.
    break;
  case 1:
    // mix a buffer and put it in place.
    mix_buffer(back_buffer);
    break;
  case 2:
    if (!initializing)
      audio_cat->warning() << "audio buffers are being starved" << endl;
    mix_buffer(current_buffer);
    mix_buffer(back_buffer);
    initializing = false;
    break;
  default:
    audio_cat->error() << "audio system wants more then 2 buffers!" << endl;
  }
}

static void* internal_update(void*) {
  if ((output_fd = open(audio_device->c_str(), O_WRONLY, 0)) == -1) {
    audio_cat->error() << "could not open '" << audio_device << "'" << endl;
    return (void*)0L;
  }
  // this one I don't know about
  int fragsize = 0x0004000c;
  if (ioctl(output_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) {
    audio_cat->error() << "faied to set fragment size" << endl;
    return (void*)0L;
  }
  // for now signed, 16-bit, little endian
  int format = AFMT_S16_LE;
  if (ioctl(output_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
    audio_cat->error() << "failed to set format on the dsp" << endl;
    return (void*)0L;
  }
  // set stereo
  int stereo = 1;
  if (ioctl(output_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
    audio_cat->error() << "failed to set stereo on the dsp" << endl;
    return (void*)0L;
  }
  // set the frequency
  if (ioctl(output_fd, SNDCTL_DSP_SPEED, &audio_mix_freq) == -1) {
    audio_cat->error() << "failed to set frequency on the dsp" << endl;
    return (void*)0L;
  }
  while (!stop_mixing) {
    if (have_buffers == 0) {
      ipc_traits::sleep(0, audio_auto_update_delay);
    } else {
      write(output_fd, current_buffer, audio_buffer_size);
      {
	mutex_lock m(buffer_mutex);
	swap_buffers();
	--have_buffers;
	++want_buffers;
      }
    }
  }
  delete [] buffer1;
  delete [] buffer2;
  delete [] scratch_buffer;
  delete [] fetch_buffer;
  delete [] zero_buffer;
  stop_mixing = false;
  audio_cat->debug() << "exiting internal thread" << endl;
  return (void*)0L;
}

static void shutdown_linux(void) {
  stop_mixing = true;
  while (stop_mixing);
  audio_cat->debug() << "I believe the internal thread has exited" << endl;
}

static void initialize(void) {
  if (have_initialized)
    return;

  buffer1 = new byte[audio_buffer_size];
  buffer2 = new byte[audio_buffer_size];
  scratch_buffer = new byte[audio_buffer_size];
  fetch_buffer = new byte[audio_buffer_size];
  zero_buffer = new byte[audio_buffer_size];

  for (int i=0; i<audio_buffer_size; ++i)
    zero_buffer[i] = 0;

  current_buffer = buffer1;
  back_buffer = buffer2;

  want_buffers = 2;
  have_buffers = 0;
  initializing = true;
  stop_mixing = false;

  audio_cat->info() << "spawning internal update thread" << endl;
  update_thread = thread::create(internal_update, (void*)0L,
				 thread::PRIORITY_NORMAL);

  AudioManager::set_update_func(update_linux);
  AudioManager::set_shutdown_func(shutdown_linux);
  have_initialized = true;
}

LinuxSample::~LinuxSample(void) {
}

float LinuxSample::length(void) {
  return (_data->get_size()) / (audio_mix_freq * sample_size);
}

AudioTraits::SampleClass::SampleStatus LinuxSample::status(void) {
  BufferSet::iterator i = buffers.find(_data);
  if (i != buffers.end())
    return AudioTraits::SampleClass::PLAYING;
  return AudioTraits::SampleClass::READY;
}

LinuxPlaying* LinuxSample::get_state(void) {
  return new LinuxPlaying();
}

void LinuxSample::destroy(AudioTraits::SampleClass* sample) {
  delete sample;
}

LinuxSample* LinuxSample::load_raw(byte* data, unsigned long size) {
  LinuxSample* ret = new LinuxSample(new Buffer(data, size));
  return ret;
}

LinuxMusic::~LinuxMusic(void) {
}

AudioTraits::MusicClass::MusicStatus LinuxMusic::status(void) {
  return AudioTraits::MusicClass::READY;
}

LinuxPlaying* LinuxMusic::get_state(void) {
  return new LinuxPlaying();
}

void LinuxMusic::destroy(AudioTraits::MusicClass* music) {
  delete music;
}

LinuxPlaying::~LinuxPlaying(void) {
}

AudioTraits::PlayingClass::PlayingStatus LinuxPlaying::status(void) {
  return AudioTraits::PlayingClass::BAD;
}

LinuxPlayer* LinuxPlayer::_global_instance = (LinuxPlayer*)0L;

LinuxPlayer::~LinuxPlayer(void) {
}

void LinuxPlayer::play_sample(AudioTraits::SampleClass* sample) {
  initialize();
  LinuxSample* lsample = (LinuxSample*)sample;
  buffers.insert(lsample->get_data());
}

void LinuxPlayer::play_music(AudioTraits::MusicClass*) {
}

void LinuxPlayer::set_volume(AudioTraits::SampleClass*, int) {
}

void LinuxPlayer::set_volume(AudioTraits::MusicClass*, int) {
}

LinuxPlayer* LinuxPlayer::get_instance(void) {
  if (_global_instance == (LinuxPlayer*)0L)
    _global_instance = new LinuxPlayer();
  return _global_instance;
}

#endif /* AUDIO_USE_LINUX */
<commit_msg>make the starving warning a debug message<commit_after>// Filename: audio_linux_traits.C
// Created by:  cary (02Oct00)
//
////////////////////////////////////////////////////////////////////

#include "audio_linux_traits.h"

#ifdef AUDIO_USE_LINUX

#include "audio_manager.h"
#include "config_audio.h"
#include <ipc_thread.h>
#include <ipc_mutex.h>
#include <set>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>

typedef set<Buffer*> BufferSet;

static bool have_initialized = false;
static mutex buffer_mutex;
static byte* buffer1;
static byte* buffer2;
static byte* current_buffer;
static byte* back_buffer;
byte* zero_buffer;
static byte* scratch_buffer;
static byte* fetch_buffer;
static int want_buffers = 0, have_buffers = 0;
static bool initializing = true;
static bool stop_mixing = false;
static int output_fd;
static thread* update_thread;
static int sample_size = sizeof(short);

BufferSet buffers;

static void swap_buffers(void) {
  byte *tmp = current_buffer;
  current_buffer = back_buffer;
  back_buffer = tmp;
}

INLINE static signed short read_buffer(byte* buf, int idx) {
  signed short ret = 0;
  switch (sample_size) {
  case 1:
    ret = *((signed char *)(&buf[idx]));
    break;
  case 2:
    ret = *((signed short *)(&buf[idx*2]));
    break;
  default:
    audio_cat->debug() << "unknown sample size (" << sample_size << ")"
		       << endl;
    break;
  }
  return ret;
}

INLINE static void write_buffer(byte* buf, int idx, signed short val) {
  switch (sample_size) {
  case 1:
    *((signed char *)(&buf[idx])) = val & 0xff;
    break;
  case 2:
    *((signed short *)(&buf[idx*2])) = val;
    break;
  default:
    audio_cat->debug() << "unknown sample size (" << sample_size << ")"
		       << endl;
    break;
  }
}

INLINE static signed short sound_clamp(signed int value) {
  signed short ret = 0;
  switch (sample_size) {
  case 1:
    ret = (value > 127)?127:((value < -128)?(-128):(value));
    break;
  case 2:
    ret = (value > 32767)?32767:((value < -32768)?(-32768):(value));
    break;
  default:
    audio_cat->debug() << "unknown sample size (" << sample_size << ")"
		       << endl;
    break;
  }
  return ret;
}

static void mix_in(byte* buf, byte* from, float vol, float pan) {
  int done = audio_buffer_size / sample_size;
  for (int i=0; i<done; i+=2) {
    signed short left = read_buffer(buf, i);
    signed short right = read_buffer(buf, i+1);

    // now get the incoming data
    signed short in_left = read_buffer(from, i);
    signed short in_right = read_buffer(from, i+1);

    // figure out panning at some point
    in_left = (short int)(in_left * vol);
    in_right = (short int)(in_right * vol);

    // compute mixed values
    left = sound_clamp(left+in_left);
    right = sound_clamp(right+in_right);

    // write it back to the buffer
    write_buffer(buf, i, left);
    write_buffer(buf, i+1, right);
  }
}

static void mix_buffer(byte* buf) {
  memcpy(scratch_buffer, zero_buffer, audio_buffer_size);
  // do stuff
  for (BufferSet::iterator i=buffers.begin(); i!=buffers.end(); ++i)
    mix_in(scratch_buffer, (*i)->get_buffer(fetch_buffer), 1., 0.);
  BufferSet to_del;
  for (BufferSet::iterator j=buffers.begin(); j!=buffers.end(); ++j)
    if ((*j)->is_done())
      to_del.insert(*j);
  {
    mutex_lock m(buffer_mutex);
    memcpy(buf, scratch_buffer, audio_buffer_size);
    --want_buffers;
    ++have_buffers;
    for (BufferSet::iterator k=to_del.begin(); k!=to_del.end(); ++k) {
      buffers.erase(*k);
      (*k)->reset();
    }
  }
}

static void update_linux(void) {
  if (buffers.empty())
    return;
  switch (want_buffers) {
  case 0:
    // all buffers are full right now.  This is a good state.
    break;
  case 1:
    // mix a buffer and put it in place.
    mix_buffer(back_buffer);
    break;
  case 2:
    if (!initializing)
      audio_cat->debug() << "audio buffers are being starved" << endl;
    mix_buffer(current_buffer);
    mix_buffer(back_buffer);
    initializing = false;
    break;
  default:
    audio_cat->error() << "audio system wants more then 2 buffers!" << endl;
  }
}

static void* internal_update(void*) {
  if ((output_fd = open(audio_device->c_str(), O_WRONLY, 0)) == -1) {
    audio_cat->error() << "could not open '" << audio_device << "'" << endl;
    return (void*)0L;
  }
  // this one I don't know about
  int fragsize = 0x0004000c;
  if (ioctl(output_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) {
    audio_cat->error() << "faied to set fragment size" << endl;
    return (void*)0L;
  }
  // for now signed, 16-bit, little endian
  int format = AFMT_S16_LE;
  if (ioctl(output_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
    audio_cat->error() << "failed to set format on the dsp" << endl;
    return (void*)0L;
  }
  // set stereo
  int stereo = 1;
  if (ioctl(output_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
    audio_cat->error() << "failed to set stereo on the dsp" << endl;
    return (void*)0L;
  }
  // set the frequency
  if (ioctl(output_fd, SNDCTL_DSP_SPEED, &audio_mix_freq) == -1) {
    audio_cat->error() << "failed to set frequency on the dsp" << endl;
    return (void*)0L;
  }
  while (!stop_mixing) {
    if (have_buffers == 0) {
      ipc_traits::sleep(0, audio_auto_update_delay);
    } else {
      write(output_fd, current_buffer, audio_buffer_size);
      {
	mutex_lock m(buffer_mutex);
	swap_buffers();
	--have_buffers;
	++want_buffers;
      }
    }
  }
  delete [] buffer1;
  delete [] buffer2;
  delete [] scratch_buffer;
  delete [] fetch_buffer;
  delete [] zero_buffer;
  stop_mixing = false;
  audio_cat->debug() << "exiting internal thread" << endl;
  return (void*)0L;
}

static void shutdown_linux(void) {
  stop_mixing = true;
  while (stop_mixing);
  audio_cat->debug() << "I believe the internal thread has exited" << endl;
}

static void initialize(void) {
  if (have_initialized)
    return;

  buffer1 = new byte[audio_buffer_size];
  buffer2 = new byte[audio_buffer_size];
  scratch_buffer = new byte[audio_buffer_size];
  fetch_buffer = new byte[audio_buffer_size];
  zero_buffer = new byte[audio_buffer_size];

  for (int i=0; i<audio_buffer_size; ++i)
    zero_buffer[i] = 0;

  current_buffer = buffer1;
  back_buffer = buffer2;

  want_buffers = 2;
  have_buffers = 0;
  initializing = true;
  stop_mixing = false;

  audio_cat->info() << "spawning internal update thread" << endl;
  update_thread = thread::create(internal_update, (void*)0L,
				 thread::PRIORITY_NORMAL);

  AudioManager::set_update_func(update_linux);
  AudioManager::set_shutdown_func(shutdown_linux);
  have_initialized = true;
}

LinuxSample::~LinuxSample(void) {
}

float LinuxSample::length(void) {
  return (_data->get_size()) / (audio_mix_freq * sample_size);
}

AudioTraits::SampleClass::SampleStatus LinuxSample::status(void) {
  BufferSet::iterator i = buffers.find(_data);
  if (i != buffers.end())
    return AudioTraits::SampleClass::PLAYING;
  return AudioTraits::SampleClass::READY;
}

LinuxPlaying* LinuxSample::get_state(void) {
  return new LinuxPlaying();
}

void LinuxSample::destroy(AudioTraits::SampleClass* sample) {
  delete sample;
}

LinuxSample* LinuxSample::load_raw(byte* data, unsigned long size) {
  LinuxSample* ret = new LinuxSample(new Buffer(data, size));
  return ret;
}

LinuxMusic::~LinuxMusic(void) {
}

AudioTraits::MusicClass::MusicStatus LinuxMusic::status(void) {
  return AudioTraits::MusicClass::READY;
}

LinuxPlaying* LinuxMusic::get_state(void) {
  return new LinuxPlaying();
}

void LinuxMusic::destroy(AudioTraits::MusicClass* music) {
  delete music;
}

LinuxPlaying::~LinuxPlaying(void) {
}

AudioTraits::PlayingClass::PlayingStatus LinuxPlaying::status(void) {
  return AudioTraits::PlayingClass::BAD;
}

LinuxPlayer* LinuxPlayer::_global_instance = (LinuxPlayer*)0L;

LinuxPlayer::~LinuxPlayer(void) {
}

void LinuxPlayer::play_sample(AudioTraits::SampleClass* sample) {
  initialize();
  LinuxSample* lsample = (LinuxSample*)sample;
  buffers.insert(lsample->get_data());
}

void LinuxPlayer::play_music(AudioTraits::MusicClass*) {
}

void LinuxPlayer::set_volume(AudioTraits::SampleClass*, int) {
}

void LinuxPlayer::set_volume(AudioTraits::MusicClass*, int) {
}

LinuxPlayer* LinuxPlayer::get_instance(void) {
  if (_global_instance == (LinuxPlayer*)0L)
    _global_instance = new LinuxPlayer();
  return _global_instance;
}

#endif /* AUDIO_USE_LINUX */
<|endoftext|>


<commit_before>// Filename: ffmpegVirtualFile.cxx
// Created by: jyelon (02Jul07)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#ifdef HAVE_FFMPEG

#include "pandabase.h"
#include "config_movies.h"
#include "ffmpegVirtualFile.h"
#include "virtualFileSystem.h"
extern "C" {
  #include "libavformat/avio.h"
}

#ifndef AVSEEK_SIZE
  #define AVSEEK_SIZE 0x10000
#endif

////////////////////////////////////////////////////////////////////
// These functions need to use C calling conventions.
////////////////////////////////////////////////////////////////////
extern "C" {
  static int       pandavfs_open(URLContext *h, const char *filename, int flags);
  static int       pandavfs_read(URLContext *h, unsigned char *buf, int size);
// This change happened a few days before 52.68.0
#if LIBAVFORMAT_VERSION_INT < 3425280
  static int       pandavfs_write(URLContext *h, unsigned char *buf, int size);
#else
  static int       pandavfs_write(URLContext *h, const unsigned char *buf, int size);
#endif
  static int64_t   pandavfs_seek(URLContext *h, int64_t pos, int whence);
  static int       pandavfs_close(URLContext *h);
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_open
//       Access: Static Function
//  Description: A hook to open a panda VFS file.
////////////////////////////////////////////////////////////////////
static int
pandavfs_open(URLContext *h, const char *filename, int flags) {
  if (flags != 0) {
    movies_cat.error() << "ffmpeg is trying to write to the VFS.\n";
    return -1;
  }
  filename += 9; // Skip over "pandavfs:"
  VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
  istream *s = vfs->open_read_file(filename, true);
  if (s == 0) {
    return -1;
  }
  // Test whether seek works.
  s->seekg(1, ios::beg);
  int tel1 = s->tellg();
  s->seekg(0, ios::beg);
  int tel2 = s->tellg();
  if (s->fail() || (tel1!=1) || (tel2!=0)) {
    movies_cat.error() << "cannot play movie (not seekable): " << h->filename << "\n";
    delete s;
    return -1;
  }
  h->priv_data = s;
  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_read
//       Access: Static Function
//  Description: A hook to read a panda VFS file.
////////////////////////////////////////////////////////////////////
static int
pandavfs_read(URLContext *h, unsigned char *buf, int size) {
  istream *s = (istream*)(h->priv_data);
  s->read((char*)buf, size);
  int gc = s->gcount();
  s->clear();
  return gc;
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_write
//       Access: Static Function
//  Description: A hook to write a panda VFS file.
////////////////////////////////////////////////////////////////////
static int
#if LIBAVFORMAT_VERSION_INT < 3425280
pandavfs_write(URLContext *h, unsigned char *buf, int size) {
#else
pandavfs_write(URLContext *h, const unsigned char *buf, int size) {
#endif
  movies_cat.error() << "ffmpeg is trying to write to the VFS.\n";
  return -1;
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_seek
//       Access: Static Function
//  Description: A hook to seek a panda VFS file.
////////////////////////////////////////////////////////////////////
static int64_t
pandavfs_seek(URLContext *h, int64_t pos, int whence) {
  istream *s = (istream*)(h->priv_data);
  switch(whence) {
  case SEEK_SET: s->seekg(pos, ios::beg); break;
  case SEEK_CUR: s->seekg(pos, ios::cur); break;
  case SEEK_END: s->seekg(pos, ios::end); break;
  case AVSEEK_SIZE: {
    s->seekg(0, ios::cur);
    int p = s->tellg();
    s->seekg(-1, ios::end);
    int size = s->tellg();
    if (size < 0) {
      movies_cat.error() << "Failed to determine filesize in ffmpegVirtualFile\n";
      s->clear();
      return -1;
    }
    size++;
    s->seekg(p, ios::beg);
    s->clear();
    return size; }
  default:
    movies_cat.error() << "Illegal parameter to seek in ffmpegVirtualFile\n";
    s->clear();
    return -1;
  }
  s->clear();
  int tl = s->tellg();
  return tl;
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_close
//       Access: Static Function
//  Description: A hook to close a panda VFS file.
////////////////////////////////////////////////////////////////////
static int
pandavfs_close(URLContext *h) {
  istream *s = (istream*)(h->priv_data);
  delete s;
  h->priv_data = 0;
  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::register_protocol
//       Access: Public, Static
//  Description: Enables ffmpeg to access panda's VFS.
//
//               After calling this method, ffmpeg will be
//               able to open "URLs" that look like this:
//
//               pandavfs:/c/mygame/foo.avi
//
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
register_protocol() {
  static bool initialized = false;
  if (initialized) {
    return;
  }
  static URLProtocol protocol;
  protocol.name = "pandavfs";
  protocol.url_open  = pandavfs_open;
  protocol.url_read  = pandavfs_read;
  protocol.url_write = pandavfs_write;
  protocol.url_seek  = pandavfs_seek;
  protocol.url_close = pandavfs_close;
#if LIBAVFORMAT_VERSION_INT < 3415296
  ::register_protocol(&protocol);
#else
  av_register_protocol(&protocol);
#endif
}

#endif // HAVE_FFMPEG
<commit_msg>include stdint.h<commit_after>// Filename: ffmpegVirtualFile.cxx
// Created by: jyelon (02Jul07)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#ifdef HAVE_FFMPEG

#include "pandabase.h"
#include "config_movies.h"
#include "ffmpegVirtualFile.h"
#include "virtualFileSystem.h"
extern "C" {
  #include "libavformat/avio.h"
}
#include <stdint.h>

#ifndef AVSEEK_SIZE
  #define AVSEEK_SIZE 0x10000
#endif

////////////////////////////////////////////////////////////////////
// These functions need to use C calling conventions.
////////////////////////////////////////////////////////////////////
extern "C" {
  static int       pandavfs_open(URLContext *h, const char *filename, int flags);
  static int       pandavfs_read(URLContext *h, unsigned char *buf, int size);
// This change happened a few days before 52.68.0
#if LIBAVFORMAT_VERSION_INT < 3425280
  static int       pandavfs_write(URLContext *h, unsigned char *buf, int size);
#else
  static int       pandavfs_write(URLContext *h, const unsigned char *buf, int size);
#endif
  static int64_t   pandavfs_seek(URLContext *h, int64_t pos, int whence);
  static int       pandavfs_close(URLContext *h);
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_open
//       Access: Static Function
//  Description: A hook to open a panda VFS file.
////////////////////////////////////////////////////////////////////
static int
pandavfs_open(URLContext *h, const char *filename, int flags) {
  if (flags != 0) {
    movies_cat.error() << "ffmpeg is trying to write to the VFS.\n";
    return -1;
  }
  filename += 9; // Skip over "pandavfs:"
  VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
  istream *s = vfs->open_read_file(filename, true);
  if (s == 0) {
    return -1;
  }
  // Test whether seek works.
  s->seekg(1, ios::beg);
  int tel1 = s->tellg();
  s->seekg(0, ios::beg);
  int tel2 = s->tellg();
  if (s->fail() || (tel1!=1) || (tel2!=0)) {
    movies_cat.error() << "cannot play movie (not seekable): " << h->filename << "\n";
    delete s;
    return -1;
  }
  h->priv_data = s;
  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_read
//       Access: Static Function
//  Description: A hook to read a panda VFS file.
////////////////////////////////////////////////////////////////////
static int
pandavfs_read(URLContext *h, unsigned char *buf, int size) {
  istream *s = (istream*)(h->priv_data);
  s->read((char*)buf, size);
  int gc = s->gcount();
  s->clear();
  return gc;
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_write
//       Access: Static Function
//  Description: A hook to write a panda VFS file.
////////////////////////////////////////////////////////////////////
static int
#if LIBAVFORMAT_VERSION_INT < 3425280
pandavfs_write(URLContext *h, unsigned char *buf, int size) {
#else
pandavfs_write(URLContext *h, const unsigned char *buf, int size) {
#endif
  movies_cat.error() << "ffmpeg is trying to write to the VFS.\n";
  return -1;
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_seek
//       Access: Static Function
//  Description: A hook to seek a panda VFS file.
////////////////////////////////////////////////////////////////////
static int64_t
pandavfs_seek(URLContext *h, int64_t pos, int whence) {
  istream *s = (istream*)(h->priv_data);
  switch(whence) {
  case SEEK_SET: s->seekg(pos, ios::beg); break;
  case SEEK_CUR: s->seekg(pos, ios::cur); break;
  case SEEK_END: s->seekg(pos, ios::end); break;
  case AVSEEK_SIZE: {
    s->seekg(0, ios::cur);
    int p = s->tellg();
    s->seekg(-1, ios::end);
    int size = s->tellg();
    if (size < 0) {
      movies_cat.error() << "Failed to determine filesize in ffmpegVirtualFile\n";
      s->clear();
      return -1;
    }
    size++;
    s->seekg(p, ios::beg);
    s->clear();
    return size; }
  default:
    movies_cat.error() << "Illegal parameter to seek in ffmpegVirtualFile\n";
    s->clear();
    return -1;
  }
  s->clear();
  int tl = s->tellg();
  return tl;
}

////////////////////////////////////////////////////////////////////
//     Function: pandavfs_close
//       Access: Static Function
//  Description: A hook to close a panda VFS file.
////////////////////////////////////////////////////////////////////
static int
pandavfs_close(URLContext *h) {
  istream *s = (istream*)(h->priv_data);
  delete s;
  h->priv_data = 0;
  return 0;
}

////////////////////////////////////////////////////////////////////
//     Function: FfmpegVirtualFile::register_protocol
//       Access: Public, Static
//  Description: Enables ffmpeg to access panda's VFS.
//
//               After calling this method, ffmpeg will be
//               able to open "URLs" that look like this:
//
//               pandavfs:/c/mygame/foo.avi
//
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
register_protocol() {
  static bool initialized = false;
  if (initialized) {
    return;
  }
  static URLProtocol protocol;
  protocol.name = "pandavfs";
  protocol.url_open  = pandavfs_open;
  protocol.url_read  = pandavfs_read;
  protocol.url_write = pandavfs_write;
  protocol.url_seek  = pandavfs_seek;
  protocol.url_close = pandavfs_close;
#if LIBAVFORMAT_VERSION_INT < 3415296
  ::register_protocol(&protocol);
#else
  av_register_protocol(&protocol);
#endif
}

#endif // HAVE_FFMPEG
<|endoftext|>


<commit_before>//@author A0094446X
#include "stdafx.h"
#include <QApplication>
#include <QList>
#include "you_main_gui.h"
#include "system_tray_manager.h"

YouMainGUI::SystemTrayManager::~SystemTrayManager() {
}

void YouMainGUI::SystemTrayManager::setup() {
	createActions();
	setIcon();
	makeContextMenu();
	connectTrayActivatedSlot();
	parentGUI->setVisible(true);
}

void YouMainGUI::SystemTrayManager::setIcon() {
	QIcon icon(":/Icon.png");
	trayIcon.setIcon(icon);
	parentGUI->setWindowIcon(icon);
	trayIcon.show();
}

void YouMainGUI::SystemTrayManager::makeContextMenu() {
	trayIconMenu = new QMenu(parentGUI);
	trayIconMenu->addAction(minimizeAction);
	trayIconMenu->addAction(maximizeAction);
	trayIconMenu->addAction(restoreAction);
	trayIconMenu->addSeparator();
	trayIconMenu->addAction(quitAction);
	trayIcon.setContextMenu(trayIconMenu);
}

void YouMainGUI::SystemTrayManager::connectTrayActivatedSlot() {
	connect(&trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
		this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
}
void YouMainGUI::SystemTrayManager::iconActivated(
	QSystemTrayIcon::ActivationReason reason) {
	if (reason == QSystemTrayIcon::Trigger) {
		if (parentGUI->isVisible() == true)
			parentGUI->hide();
		else
			parentGUI->show();
	}
}

void YouMainGUI::SystemTrayManager::createActions() {
	minimizeAction = new QAction(tr("Minimize"), parentGUI);
	connect(minimizeAction, SIGNAL(triggered()), parentGUI, SLOT(hide()));

	maximizeAction = new QAction(tr("Maximize"), parentGUI);
	connect(maximizeAction, SIGNAL(triggered()), parentGUI, SLOT(showMaximized()));

	restoreAction = new QAction(tr("Restore"), parentGUI);
	connect(restoreAction, SIGNAL(triggered()), parentGUI, SLOT(showNormal()));

	quitAction = new QAction(tr("Quit"), parentGUI);
	connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
}
<commit_msg>Logic fix for icon activation.<commit_after>//@author A0094446X
#include "stdafx.h"
#include <QApplication>
#include <QList>
#include "you_main_gui.h"
#include "system_tray_manager.h"

YouMainGUI::SystemTrayManager::~SystemTrayManager() {
}

void YouMainGUI::SystemTrayManager::setup() {
	createActions();
	setIcon();
	makeContextMenu();
	connectTrayActivatedSlot();
	parentGUI->setVisible(true);
}

void YouMainGUI::SystemTrayManager::setIcon() {
	QIcon icon(":/Icon.png");
	trayIcon.setIcon(icon);
	parentGUI->setWindowIcon(icon);
	trayIcon.show();
}

void YouMainGUI::SystemTrayManager::makeContextMenu() {
	trayIconMenu = new QMenu(parentGUI);
	trayIconMenu->addAction(minimizeAction);
	trayIconMenu->addAction(maximizeAction);
	trayIconMenu->addAction(restoreAction);
	trayIconMenu->addSeparator();
	trayIconMenu->addAction(quitAction);
	trayIcon.setContextMenu(trayIconMenu);
}

void YouMainGUI::SystemTrayManager::connectTrayActivatedSlot() {
	connect(&trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
		this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
}

void YouMainGUI::SystemTrayManager::iconActivated(
	QSystemTrayIcon::ActivationReason reason) {
	if (reason == QSystemTrayIcon::Trigger) {
		bool visible = parentGUI->isVisible();
		bool minimized = parentGUI->isMinimized();
		assert( (visible == true && minimized == true) ||
				(visible == true && minimized == false) ||
				(visible == false));
		Qt::WindowStates toggleState
			(parentGUI->windowState() & ~Qt::WindowMinimized);
		// Visible and minimized
		if (visible && minimized) {
			parentGUI->setWindowState(toggleState | Qt::WindowActive);
		} // Visible and not minimized
		else if (visible && !minimized) {
			parentGUI->setWindowState(toggleState | Qt::WindowActive);
			parentGUI->hide();
		} else if (!visible) { // Not visible
			parentGUI->show();
			parentGUI->setWindowState(toggleState | Qt::WindowActive);
		}
	}
}

void YouMainGUI::SystemTrayManager::createActions() {
	minimizeAction = new QAction(tr("Minimize"), parentGUI);
	connect(minimizeAction, SIGNAL(triggered()), parentGUI, SLOT(hide()));

	maximizeAction = new QAction(tr("Maximize"), parentGUI);
	connect(maximizeAction, SIGNAL(triggered()), parentGUI, SLOT(showMaximized()));

	restoreAction = new QAction(tr("Restore"), parentGUI);
	connect(restoreAction, SIGNAL(triggered()), parentGUI, SLOT(showNormal()));

	quitAction = new QAction(tr("Quit"), parentGUI);
	connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
}
<|endoftext|>


<commit_before>#include "../gtest/include/gtest/gtest.h"
#include <string.h>		// use memset/memcmp
#include "../codec/encoder/core/inc/memory_align.h"

using namespace WelsSVCEnc;

//Tests of WelsGetCacheLineSize Begin
TEST(MemoryAlignTest, GetCacheLineSize_LoopWithin16K)
{
  const unsigned int kuiTestBoundary16K = 16 * 1024;
	unsigned int uiTargetAlign = 1;
	while (uiTargetAlign < kuiTestBoundary16K) {
		CMemoryAlign cTestMa(uiTargetAlign);
    ASSERT_EQ(  (uiTargetAlign & 0x0F)?16:uiTargetAlign, cTestMa.WelsGetCacheLineSize() );
		++ uiTargetAlign;
	}
}

TEST(MemoryAlignTest, GetCacheLineSize_Zero)
{
  CMemoryAlign cTestMa(0);
  ASSERT_EQ(  16, cTestMa.WelsGetCacheLineSize() );
}
TEST(MemoryAlignTest, GetCacheLineSize_MaxUINT)
{
	CMemoryAlign cTestMa(0xFFFFFFFF);
	ASSERT_EQ( 16, cTestMa.WelsGetCacheLineSize() );
}
//Tests of WelsGetCacheLineSize End
//Tests of WelsMallocAndFree Begin
TEST(MemoryAlignTest, WelsMallocAndFreeOnceFunctionVerify)
{
  const uint32_t kuiTargetAlignSize[4] = {32, 16, 64, 8};
  srand((uint32_t)time(NULL));

  for (int i=0; i<4; i++) {
    const uint32_t kuiTestAlignSize	= kuiTargetAlignSize[i];
    const uint32_t kuiTestDataSize		= abs(rand());

    CMemoryAlign cTestMa(kuiTestAlignSize);
    const uint32_t uiSize = kuiTestDataSize;
    const char strUnitTestTag[100] = "pUnitTestData";
    const uint32_t kuiUsedCacheLineSize	= ((kuiTestAlignSize == 0) || (kuiTestAlignSize & 0x0F)) ? (16) : (kuiTestAlignSize);
    const uint32_t kuiExtraAlignSize	= kuiUsedCacheLineSize-1;
    const uint32_t kuiExpectedSize	= sizeof( void ** ) + sizeof( int32_t ) + kuiExtraAlignSize + uiSize;
    uint8_t *pUnitTestData = static_cast<uint8_t *>(cTestMa.WelsMalloc(uiSize, strUnitTestTag));
    if ( pUnitTestData != NULL ) {
      ASSERT_TRUE( (((int64_t)(static_cast<void *>(pUnitTestData))) & kuiExtraAlignSize) == 0 );
      EXPECT_EQ( kuiExpectedSize, cTestMa.WelsGetMemoryUsage() );
      cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
    }
    else {
      EXPECT_EQ( NULL, pUnitTestData );
      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
      cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
    }
  }
}

<commit_msg>Include time.h in the MemoryAlloc test<commit_after>#include "../gtest/include/gtest/gtest.h"
#include <string.h>		// use memset/memcmp
#include <time.h>
#include "../codec/encoder/core/inc/memory_align.h"

using namespace WelsSVCEnc;

//Tests of WelsGetCacheLineSize Begin
TEST(MemoryAlignTest, GetCacheLineSize_LoopWithin16K)
{
  const unsigned int kuiTestBoundary16K = 16 * 1024;
	unsigned int uiTargetAlign = 1;
	while (uiTargetAlign < kuiTestBoundary16K) {
		CMemoryAlign cTestMa(uiTargetAlign);
    ASSERT_EQ(  (uiTargetAlign & 0x0F)?16:uiTargetAlign, cTestMa.WelsGetCacheLineSize() );
		++ uiTargetAlign;
	}
}

TEST(MemoryAlignTest, GetCacheLineSize_Zero)
{
  CMemoryAlign cTestMa(0);
  ASSERT_EQ(  16, cTestMa.WelsGetCacheLineSize() );
}
TEST(MemoryAlignTest, GetCacheLineSize_MaxUINT)
{
	CMemoryAlign cTestMa(0xFFFFFFFF);
	ASSERT_EQ( 16, cTestMa.WelsGetCacheLineSize() );
}
//Tests of WelsGetCacheLineSize End
//Tests of WelsMallocAndFree Begin
TEST(MemoryAlignTest, WelsMallocAndFreeOnceFunctionVerify)
{
  const uint32_t kuiTargetAlignSize[4] = {32, 16, 64, 8};
  srand((uint32_t)time(NULL));

  for (int i=0; i<4; i++) {
    const uint32_t kuiTestAlignSize	= kuiTargetAlignSize[i];
    const uint32_t kuiTestDataSize		= abs(rand());

    CMemoryAlign cTestMa(kuiTestAlignSize);
    const uint32_t uiSize = kuiTestDataSize;
    const char strUnitTestTag[100] = "pUnitTestData";
    const uint32_t kuiUsedCacheLineSize	= ((kuiTestAlignSize == 0) || (kuiTestAlignSize & 0x0F)) ? (16) : (kuiTestAlignSize);
    const uint32_t kuiExtraAlignSize	= kuiUsedCacheLineSize-1;
    const uint32_t kuiExpectedSize	= sizeof( void ** ) + sizeof( int32_t ) + kuiExtraAlignSize + uiSize;
    uint8_t *pUnitTestData = static_cast<uint8_t *>(cTestMa.WelsMalloc(uiSize, strUnitTestTag));
    if ( pUnitTestData != NULL ) {
      ASSERT_TRUE( (((int64_t)(static_cast<void *>(pUnitTestData))) & kuiExtraAlignSize) == 0 );
      EXPECT_EQ( kuiExpectedSize, cTestMa.WelsGetMemoryUsage() );
      cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
    }
    else {
      EXPECT_EQ( NULL, pUnitTestData );
      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
      cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
      EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() );
    }
  }
}

<|endoftext|>


<commit_before>/*************************************************************************/
/*  gdscript_cache.cpp                                                   */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "gdscript_cache.h"

#include "core/io/file_access.h"
#include "core/templates/vector.h"
#include "gdscript.h"
#include "gdscript_analyzer.h"
#include "gdscript_parser.h"

bool GDScriptParserRef::is_valid() const {
	return parser != nullptr;
}

GDScriptParserRef::Status GDScriptParserRef::get_status() const {
	return status;
}

GDScriptParser *GDScriptParserRef::get_parser() const {
	return parser;
}

Error GDScriptParserRef::raise_status(Status p_new_status) {
	ERR_FAIL_COND_V(parser == nullptr, ERR_INVALID_DATA);

	if (result != OK) {
		return result;
	}

	while (p_new_status > status) {
		switch (status) {
			case EMPTY:
				status = PARSED;
				result = parser->parse(GDScriptCache::get_source_code(path), path, false);
				break;
			case PARSED: {
				analyzer = memnew(GDScriptAnalyzer(parser));
				status = INHERITANCE_SOLVED;
				Error inheritance_result = analyzer->resolve_inheritance();
				if (result == OK) {
					result = inheritance_result;
				}
			} break;
			case INHERITANCE_SOLVED: {
				status = INTERFACE_SOLVED;
				Error interface_result = analyzer->resolve_interface();
				if (result == OK) {
					result = interface_result;
				}
			} break;
			case INTERFACE_SOLVED: {
				status = FULLY_SOLVED;
				Error body_result = analyzer->resolve_body();
				if (result == OK) {
					result = body_result;
				}
			} break;
			case FULLY_SOLVED: {
				return result;
			}
		}
		if (result != OK) {
			return result;
		}
	}

	return result;
}

GDScriptParserRef::~GDScriptParserRef() {
	if (parser != nullptr) {
		memdelete(parser);
	}
	if (analyzer != nullptr) {
		memdelete(analyzer);
	}
	MutexLock lock(GDScriptCache::singleton->lock);
	GDScriptCache::singleton->parser_map.erase(path);
}

GDScriptCache *GDScriptCache::singleton = nullptr;

void GDScriptCache::remove_script(const String &p_path) {
	MutexLock lock(singleton->lock);
	singleton->shallow_gdscript_cache.erase(p_path);
	singleton->full_gdscript_cache.erase(p_path);
}

Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptParserRef::Status p_status, Error &r_error, const String &p_owner) {
	MutexLock lock(singleton->lock);
	Ref<GDScriptParserRef> ref;
	if (!p_owner.is_empty()) {
		singleton->dependencies[p_owner].insert(p_path);
	}
	if (singleton->parser_map.has(p_path)) {
		ref = Ref<GDScriptParserRef>(singleton->parser_map[p_path]);
	} else {
		if (!FileAccess::exists(p_path)) {
			r_error = ERR_FILE_NOT_FOUND;
			return ref;
		}
		GDScriptParser *parser = memnew(GDScriptParser);
		ref.instantiate();
		ref->parser = parser;
		ref->path = p_path;
		singleton->parser_map[p_path] = ref.ptr();
	}

	r_error = ref->raise_status(p_status);

	return ref;
}

String GDScriptCache::get_source_code(const String &p_path) {
	Vector<uint8_t> source_file;
	Error err;
	FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
	if (err) {
		ERR_FAIL_COND_V(err, "");
	}

	uint64_t len = f->get_length();
	source_file.resize(len + 1);
	uint64_t r = f->get_buffer(source_file.ptrw(), len);
	f->close();
	ERR_FAIL_COND_V(r != len, "");
	source_file.write[len] = 0;

	String source;
	if (source.parse_utf8((const char *)source_file.ptr())) {
		ERR_FAIL_V_MSG("", "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
	}
	return source;
}

Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const String &p_owner) {
	MutexLock lock(singleton->lock);
	if (!p_owner.is_empty()) {
		singleton->dependencies[p_owner].insert(p_path);
	}
	if (singleton->full_gdscript_cache.has(p_path)) {
		return singleton->full_gdscript_cache[p_path];
	}
	if (singleton->shallow_gdscript_cache.has(p_path)) {
		return singleton->shallow_gdscript_cache[p_path];
	}

	Ref<GDScript> script;
	script.instantiate();
	script->set_path(p_path, true);
	script->set_script_path(p_path);
	script->load_source_code(p_path);

	singleton->shallow_gdscript_cache[p_path] = script.ptr();
	return script;
}

Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner) {
	MutexLock lock(singleton->lock);

	if (!p_owner.is_empty()) {
		singleton->dependencies[p_owner].insert(p_path);
	}

	r_error = OK;
	if (singleton->full_gdscript_cache.has(p_path)) {
		Ref<GDScript> script = singleton->full_gdscript_cache[p_path];
#ifdef TOOLS_ENABLED
		uint64_t mt = FileAccess::get_modified_time(p_path);
		if (script->get_last_modified_time() == mt) {
			return script;
		}
#else
		return script;
#endif //TOOLS_ENABLED
	}

	Ref<GDScript> script = get_shallow_script(p_path);
	ERR_FAIL_COND_V(script.is_null(), Ref<GDScript>());

	r_error = script->load_source_code(p_path);

	if (r_error) {
		return script;
	}

	r_error = script->reload();
	if (r_error) {
		return script;
	}

	singleton->full_gdscript_cache[p_path] = script.ptr();
	singleton->shallow_gdscript_cache.erase(p_path);

	return script;
}

Error GDScriptCache::finish_compiling(const String &p_owner) {
	// Mark this as compiled.
	Ref<GDScript> script = get_shallow_script(p_owner);
	singleton->full_gdscript_cache[p_owner] = script.ptr();
	singleton->shallow_gdscript_cache.erase(p_owner);

	Set<String> depends = singleton->dependencies[p_owner];

	Error err = OK;
	for (const Set<String>::Element *E = depends.front(); E != nullptr; E = E->next()) {
		Error this_err = OK;
		// No need to save the script. We assume it's already referenced in the owner.
		get_full_script(E->get(), this_err);

		if (this_err != OK) {
			err = this_err;
		}
	}

	singleton->dependencies.erase(p_owner);

	return err;
}

GDScriptCache::GDScriptCache() {
	singleton = this;
}

GDScriptCache::~GDScriptCache() {
	parser_map.clear();
	shallow_gdscript_cache.clear();
	full_gdscript_cache.clear();
	singleton = nullptr;
}
<commit_msg>Revert "Fix auto reload scripts on external change"<commit_after>/*************************************************************************/
/*  gdscript_cache.cpp                                                   */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "gdscript_cache.h"

#include "core/io/file_access.h"
#include "core/templates/vector.h"
#include "gdscript.h"
#include "gdscript_analyzer.h"
#include "gdscript_parser.h"

bool GDScriptParserRef::is_valid() const {
	return parser != nullptr;
}

GDScriptParserRef::Status GDScriptParserRef::get_status() const {
	return status;
}

GDScriptParser *GDScriptParserRef::get_parser() const {
	return parser;
}

Error GDScriptParserRef::raise_status(Status p_new_status) {
	ERR_FAIL_COND_V(parser == nullptr, ERR_INVALID_DATA);

	if (result != OK) {
		return result;
	}

	while (p_new_status > status) {
		switch (status) {
			case EMPTY:
				status = PARSED;
				result = parser->parse(GDScriptCache::get_source_code(path), path, false);
				break;
			case PARSED: {
				analyzer = memnew(GDScriptAnalyzer(parser));
				status = INHERITANCE_SOLVED;
				Error inheritance_result = analyzer->resolve_inheritance();
				if (result == OK) {
					result = inheritance_result;
				}
			} break;
			case INHERITANCE_SOLVED: {
				status = INTERFACE_SOLVED;
				Error interface_result = analyzer->resolve_interface();
				if (result == OK) {
					result = interface_result;
				}
			} break;
			case INTERFACE_SOLVED: {
				status = FULLY_SOLVED;
				Error body_result = analyzer->resolve_body();
				if (result == OK) {
					result = body_result;
				}
			} break;
			case FULLY_SOLVED: {
				return result;
			}
		}
		if (result != OK) {
			return result;
		}
	}

	return result;
}

GDScriptParserRef::~GDScriptParserRef() {
	if (parser != nullptr) {
		memdelete(parser);
	}
	if (analyzer != nullptr) {
		memdelete(analyzer);
	}
	MutexLock lock(GDScriptCache::singleton->lock);
	GDScriptCache::singleton->parser_map.erase(path);
}

GDScriptCache *GDScriptCache::singleton = nullptr;

void GDScriptCache::remove_script(const String &p_path) {
	MutexLock lock(singleton->lock);
	singleton->shallow_gdscript_cache.erase(p_path);
	singleton->full_gdscript_cache.erase(p_path);
}

Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptParserRef::Status p_status, Error &r_error, const String &p_owner) {
	MutexLock lock(singleton->lock);
	Ref<GDScriptParserRef> ref;
	if (!p_owner.is_empty()) {
		singleton->dependencies[p_owner].insert(p_path);
	}
	if (singleton->parser_map.has(p_path)) {
		ref = Ref<GDScriptParserRef>(singleton->parser_map[p_path]);
	} else {
		if (!FileAccess::exists(p_path)) {
			r_error = ERR_FILE_NOT_FOUND;
			return ref;
		}
		GDScriptParser *parser = memnew(GDScriptParser);
		ref.instantiate();
		ref->parser = parser;
		ref->path = p_path;
		singleton->parser_map[p_path] = ref.ptr();
	}

	r_error = ref->raise_status(p_status);

	return ref;
}

String GDScriptCache::get_source_code(const String &p_path) {
	Vector<uint8_t> source_file;
	Error err;
	FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
	if (err) {
		ERR_FAIL_COND_V(err, "");
	}

	uint64_t len = f->get_length();
	source_file.resize(len + 1);
	uint64_t r = f->get_buffer(source_file.ptrw(), len);
	f->close();
	ERR_FAIL_COND_V(r != len, "");
	source_file.write[len] = 0;

	String source;
	if (source.parse_utf8((const char *)source_file.ptr())) {
		ERR_FAIL_V_MSG("", "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
	}
	return source;
}

Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const String &p_owner) {
	MutexLock lock(singleton->lock);
	if (!p_owner.is_empty()) {
		singleton->dependencies[p_owner].insert(p_path);
	}
	if (singleton->full_gdscript_cache.has(p_path)) {
		return singleton->full_gdscript_cache[p_path];
	}
	if (singleton->shallow_gdscript_cache.has(p_path)) {
		return singleton->shallow_gdscript_cache[p_path];
	}

	Ref<GDScript> script;
	script.instantiate();
	script->set_path(p_path, true);
	script->set_script_path(p_path);
	script->load_source_code(p_path);

	singleton->shallow_gdscript_cache[p_path] = script.ptr();
	return script;
}

Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner) {
	MutexLock lock(singleton->lock);

	if (!p_owner.is_empty()) {
		singleton->dependencies[p_owner].insert(p_path);
	}

	r_error = OK;
	if (singleton->full_gdscript_cache.has(p_path)) {
		return singleton->full_gdscript_cache[p_path];
	}

	Ref<GDScript> script = get_shallow_script(p_path);
	ERR_FAIL_COND_V(script.is_null(), Ref<GDScript>());

	r_error = script->load_source_code(p_path);

	if (r_error) {
		return script;
	}

	r_error = script->reload();
	if (r_error) {
		return script;
	}

	singleton->full_gdscript_cache[p_path] = script.ptr();
	singleton->shallow_gdscript_cache.erase(p_path);

	return script;
}

Error GDScriptCache::finish_compiling(const String &p_owner) {
	// Mark this as compiled.
	Ref<GDScript> script = get_shallow_script(p_owner);
	singleton->full_gdscript_cache[p_owner] = script.ptr();
	singleton->shallow_gdscript_cache.erase(p_owner);

	Set<String> depends = singleton->dependencies[p_owner];

	Error err = OK;
	for (const Set<String>::Element *E = depends.front(); E != nullptr; E = E->next()) {
		Error this_err = OK;
		// No need to save the script. We assume it's already referenced in the owner.
		get_full_script(E->get(), this_err);

		if (this_err != OK) {
			err = this_err;
		}
	}

	singleton->dependencies.erase(p_owner);

	return err;
}

GDScriptCache::GDScriptCache() {
	singleton = this;
}

GDScriptCache::~GDScriptCache() {
	parser_map.clear();
	shallow_gdscript_cache.clear();
	full_gdscript_cache.clear();
	singleton = nullptr;
}
<|endoftext|>


<commit_before>#include "adaptive_load/adaptive_load_controller_impl.h"

#include <chrono>

#include "envoy/common/exception.h"
#include "envoy/config/core/v3/base.pb.h"

#include "nighthawk/adaptive_load/adaptive_load_controller.h"
#include "nighthawk/adaptive_load/metrics_plugin.h"
#include "nighthawk/adaptive_load/scoring_function.h"
#include "nighthawk/adaptive_load/step_controller.h"

#include "external/envoy/source/common/common/logger.h"
#include "external/envoy/source/common/common/statusor.h"
#include "external/envoy/source/common/protobuf/protobuf.h"

#include "api/adaptive_load/adaptive_load.pb.h"
#include "api/adaptive_load/benchmark_result.pb.h"
#include "api/adaptive_load/metric_spec.pb.h"
#include "api/client/options.pb.h"
#include "api/client/output.pb.h"
#include "api/client/service.grpc.pb.h"

#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "adaptive_load/metrics_plugin_impl.h"
#include "adaptive_load/plugin_loader.h"

namespace Nighthawk {

namespace {

using nighthawk::adaptive_load::AdaptiveLoadSessionOutput;
using nighthawk::adaptive_load::AdaptiveLoadSessionSpec;
using nighthawk::adaptive_load::BenchmarkResult;
using nighthawk::adaptive_load::MetricEvaluation;
using nighthawk::adaptive_load::MetricSpec;
using nighthawk::adaptive_load::MetricSpecWithThreshold;
using nighthawk::adaptive_load::ThresholdSpec;

/**
 * Loads and initializes MetricsPlugins requested in the session spec. Assumes the spec has already
 * been validated; crashes the process otherwise.
 *
 * @param spec Adaptive load session spec proto that has already been validated.
 *
 * @return Map from MetricsPlugin names to initialized plugins, to be used in the course of a single
 * adaptive load session based on the session spec.
 */
absl::flat_hash_map<std::string, MetricsPluginPtr>
LoadMetricsPlugins(const AdaptiveLoadSessionSpec& spec) {
  absl::flat_hash_map<std::string, MetricsPluginPtr> name_to_custom_metrics_plugin_map;
  for (const envoy::config::core::v3::TypedExtensionConfig& config :
       spec.metrics_plugin_configs()) {
    absl::StatusOr<MetricsPluginPtr> metrics_plugin_or = LoadMetricsPlugin(config);
    RELEASE_ASSERT(
        metrics_plugin_or.ok(),
        absl::StrCat(
            "MetricsPlugin loading error should have been caught during input validation: ",
            metrics_plugin_or.status().message()));
    name_to_custom_metrics_plugin_map[config.name()] = std::move(metrics_plugin_or.value());
  }
  return name_to_custom_metrics_plugin_map;
}

/**
 * Loads and initializes a StepController plugin requested in the session spec. Assumes
 * the spec has already been validated; crashes the process otherwise.
 *
 * @param spec Adaptive load session spec proto that has already been validated.
 *
 * @return unique_ptr<StepController> Initialized StepController plugin.
 */
StepControllerPtr LoadStepControllerPluginFromSpec(const AdaptiveLoadSessionSpec& spec) {
  absl::StatusOr<StepControllerPtr> step_controller_or =
      LoadStepControllerPlugin(spec.step_controller_config(), spec.nighthawk_traffic_template());
  RELEASE_ASSERT(
      step_controller_or.ok(),
      absl::StrCat(
          "StepController plugin loading error should have been caught during input validation: ",
          step_controller_or.status().message()));
  return std::move(step_controller_or.value());
}

} // namespace

AdaptiveLoadControllerImpl::AdaptiveLoadControllerImpl(
    const NighthawkServiceClient& nighthawk_service_client,
    const MetricsEvaluator& metrics_evaluator,
    const AdaptiveLoadSessionSpecProtoHelper& session_spec_proto_helper,
    Envoy::TimeSource& time_source)
    : nighthawk_service_client_{nighthawk_service_client}, metrics_evaluator_{metrics_evaluator},
      session_spec_proto_helper_{session_spec_proto_helper}, time_source_{time_source} {}

absl::StatusOr<BenchmarkResult> AdaptiveLoadControllerImpl::PerformAndAnalyzeNighthawkBenchmark(
    nighthawk::client::NighthawkService::StubInterface* nighthawk_service_stub,
    const AdaptiveLoadSessionSpec& spec,
    const absl::flat_hash_map<std::string, MetricsPluginPtr>& name_to_custom_plugin_map,
    StepController& step_controller, Envoy::ProtobufWkt::Duration duration) {
  absl::StatusOr<nighthawk::client::CommandLineOptions> command_line_options_or =
      step_controller.GetCurrentCommandLineOptions();
  if (!command_line_options_or.ok()) {
    ENVOY_LOG_MISC(error, "Error constructing Nighthawk input: {}: {}",
                   command_line_options_or.status().code(),
                   command_line_options_or.status().message());
    return command_line_options_or.status();
  }
  nighthawk::client::CommandLineOptions command_line_options = command_line_options_or.value();
  // Overwrite the duration in the traffic template with the specified duration of the adjusting
  // or testing stage.
  *command_line_options.mutable_duration() = std::move(duration);

  ENVOY_LOG_MISC(info, "Sending load: {}", command_line_options.DebugString());
  absl::StatusOr<nighthawk::client::ExecutionResponse> nighthawk_response_or =
      nighthawk_service_client_.PerformNighthawkBenchmark(nighthawk_service_stub,
                                                          command_line_options);
  if (!nighthawk_response_or.ok()) {
    ENVOY_LOG_MISC(error, "Nighthawk Service error: {}: {}", nighthawk_response_or.status().code(),
                   nighthawk_response_or.status().message());
    return nighthawk_response_or.status();
  }
  nighthawk::client::ExecutionResponse nighthawk_response = nighthawk_response_or.value();

  absl::StatusOr<BenchmarkResult> benchmark_result_or =
      metrics_evaluator_.AnalyzeNighthawkBenchmark(nighthawk_response, spec,
                                                   name_to_custom_plugin_map);
  if (!benchmark_result_or.ok()) {
    ENVOY_LOG_MISC(error, "Benchmark scoring error: {}: {}", benchmark_result_or.status().code(),
                   benchmark_result_or.status().message());
    return benchmark_result_or.status();
  }
  BenchmarkResult benchmark_result = benchmark_result_or.value();
  for (const MetricEvaluation& evaluation : benchmark_result.metric_evaluations()) {
    ENVOY_LOG_MISC(info, "Evaluation: {}", evaluation.DebugString());
  }
  step_controller.UpdateAndRecompute(benchmark_result);
  return benchmark_result;
}

absl::StatusOr<AdaptiveLoadSessionOutput> AdaptiveLoadControllerImpl::PerformAdaptiveLoadSession(
    nighthawk::client::NighthawkService::StubInterface* nighthawk_service_stub,
    const AdaptiveLoadSessionSpec& input_spec) {
  AdaptiveLoadSessionSpec spec = session_spec_proto_helper_.SetSessionSpecDefaults(input_spec);
  absl::Status validation_status = session_spec_proto_helper_.CheckSessionSpec(spec);
  if (!validation_status.ok()) {
    ENVOY_LOG_MISC(error, "Validation failed: {}", validation_status.message());
    return validation_status;
  }
  absl::flat_hash_map<std::string, MetricsPluginPtr> name_to_custom_metrics_plugin_map =
      LoadMetricsPlugins(spec);
  StepControllerPtr step_controller = LoadStepControllerPluginFromSpec(spec);
  AdaptiveLoadSessionOutput output;

  // Threshold specs are reproduced in the output proto for convenience.
  for (const nighthawk::adaptive_load::MetricSpecWithThreshold& threshold :
       spec.metric_thresholds()) {
    *output.mutable_metric_thresholds()->Add() = threshold;
  }

  // Perform adjusting stage:
  Envoy::MonotonicTime start_time = time_source_.monotonicTime();
  std::string doom_reason;
  do {
    absl::StatusOr<BenchmarkResult> result_or = PerformAndAnalyzeNighthawkBenchmark(
        nighthawk_service_stub, spec, name_to_custom_metrics_plugin_map, *step_controller,
        spec.measuring_period());
    if (!result_or.ok()) {
      return result_or.status();
    }
    BenchmarkResult result = result_or.value();
    *output.mutable_adjusting_stage_results()->Add() = result;

    if (spec.has_benchmark_cooldown_duration()) {
      ENVOY_LOG_MISC(info, "Cooling down before the next benchmark for duration: {}",
                     spec.benchmark_cooldown_duration());
      uint64_t sleep_time_ms = Envoy::Protobuf::util::TimeUtil::DurationToMilliseconds(
          spec.benchmark_cooldown_duration());
      absl::SleepFor(absl::Milliseconds(sleep_time_ms));
    }

    const std::chrono::nanoseconds time_limit_ns(
        Envoy::Protobuf::util::TimeUtil::DurationToNanoseconds(spec.convergence_deadline()));
    const auto elapsed_time_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
        time_source_.monotonicTime() - start_time);
    if (elapsed_time_ns > time_limit_ns) {
      std::string message = absl::StrFormat("Failed to converge before deadline of %.2f seconds.",
                                            time_limit_ns.count() / 1e9);
      ENVOY_LOG_MISC(error, message);
      return absl::DeadlineExceededError(message);
    }
  } while (!step_controller->IsConverged() && !step_controller->IsDoomed(doom_reason));

  if (step_controller->IsDoomed(doom_reason)) {
    std::string message =
        absl::StrCat("Step controller determined that it can never converge: ", doom_reason);
    ENVOY_LOG_MISC(error, message);
    return absl::AbortedError(message);
  }

  // Perform testing stage:
  absl::StatusOr<BenchmarkResult> result_or = PerformAndAnalyzeNighthawkBenchmark(
      nighthawk_service_stub, spec, name_to_custom_metrics_plugin_map, *step_controller,
      spec.testing_stage_duration());
  if (!result_or.ok()) {
    return result_or.status();
  }
  *output.mutable_testing_stage_result() = result_or.value();
  return output;
}

} // namespace Nighthawk
<commit_msg>Log a stripped down version of the NH output for the adaptive load session. (#680)<commit_after>#include "adaptive_load/adaptive_load_controller_impl.h"

#include <chrono>

#include "envoy/common/exception.h"
#include "envoy/config/core/v3/base.pb.h"

#include "nighthawk/adaptive_load/adaptive_load_controller.h"
#include "nighthawk/adaptive_load/metrics_plugin.h"
#include "nighthawk/adaptive_load/scoring_function.h"
#include "nighthawk/adaptive_load/step_controller.h"

#include "external/envoy/source/common/common/logger.h"
#include "external/envoy/source/common/common/statusor.h"
#include "external/envoy/source/common/protobuf/protobuf.h"

#include "api/adaptive_load/adaptive_load.pb.h"
#include "api/adaptive_load/benchmark_result.pb.h"
#include "api/adaptive_load/metric_spec.pb.h"
#include "api/client/options.pb.h"
#include "api/client/output.pb.h"
#include "api/client/service.grpc.pb.h"

#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "adaptive_load/metrics_plugin_impl.h"
#include "adaptive_load/plugin_loader.h"

namespace Nighthawk {

namespace {

using nighthawk::adaptive_load::AdaptiveLoadSessionOutput;
using nighthawk::adaptive_load::AdaptiveLoadSessionSpec;
using nighthawk::adaptive_load::BenchmarkResult;
using nighthawk::adaptive_load::MetricEvaluation;
using nighthawk::adaptive_load::MetricSpec;
using nighthawk::adaptive_load::MetricSpecWithThreshold;
using nighthawk::adaptive_load::ThresholdSpec;

/**
 * Loads and initializes MetricsPlugins requested in the session spec. Assumes the spec has already
 * been validated; crashes the process otherwise.
 *
 * @param spec Adaptive load session spec proto that has already been validated.
 *
 * @return Map from MetricsPlugin names to initialized plugins, to be used in the course of a single
 * adaptive load session based on the session spec.
 */
absl::flat_hash_map<std::string, MetricsPluginPtr>
LoadMetricsPlugins(const AdaptiveLoadSessionSpec& spec) {
  absl::flat_hash_map<std::string, MetricsPluginPtr> name_to_custom_metrics_plugin_map;
  for (const envoy::config::core::v3::TypedExtensionConfig& config :
       spec.metrics_plugin_configs()) {
    absl::StatusOr<MetricsPluginPtr> metrics_plugin_or = LoadMetricsPlugin(config);
    RELEASE_ASSERT(
        metrics_plugin_or.ok(),
        absl::StrCat(
            "MetricsPlugin loading error should have been caught during input validation: ",
            metrics_plugin_or.status().message()));
    name_to_custom_metrics_plugin_map[config.name()] = std::move(metrics_plugin_or.value());
  }
  return name_to_custom_metrics_plugin_map;
}

/**
 * Logs the execution response excluding all non-global results and the
 * statistics from the global result.
 *
 * @param response is the execution response that should be logged.
 */
void LogGlobalResultExcludingStatistics(const nighthawk::client::ExecutionResponse& response) {
  nighthawk::client::ExecutionResponse stripped = response;
  stripped.mutable_output()->clear_results();
  for (const nighthawk::client::Result& result : response.output().results()) {
    if (result.name() != "global") {
      continue;
    }
    nighthawk::client::Result* stripped_result = stripped.mutable_output()->add_results();
    *stripped_result = result;
    stripped_result->clear_statistics();
  }
  ENVOY_LOG_MISC(info,
                 "Got result (stripped to just the global result excluding "
                 "statistics): {}",
                 stripped.DebugString());
}

/**
 * Loads and initializes a StepController plugin requested in the session spec. Assumes
 * the spec has already been validated; crashes the process otherwise.
 *
 * @param spec Adaptive load session spec proto that has already been validated.
 *
 * @return unique_ptr<StepController> Initialized StepController plugin.
 */
StepControllerPtr LoadStepControllerPluginFromSpec(const AdaptiveLoadSessionSpec& spec) {
  absl::StatusOr<StepControllerPtr> step_controller_or =
      LoadStepControllerPlugin(spec.step_controller_config(), spec.nighthawk_traffic_template());
  RELEASE_ASSERT(
      step_controller_or.ok(),
      absl::StrCat(
          "StepController plugin loading error should have been caught during input validation: ",
          step_controller_or.status().message()));
  return std::move(step_controller_or.value());
}

} // namespace

AdaptiveLoadControllerImpl::AdaptiveLoadControllerImpl(
    const NighthawkServiceClient& nighthawk_service_client,
    const MetricsEvaluator& metrics_evaluator,
    const AdaptiveLoadSessionSpecProtoHelper& session_spec_proto_helper,
    Envoy::TimeSource& time_source)
    : nighthawk_service_client_{nighthawk_service_client}, metrics_evaluator_{metrics_evaluator},
      session_spec_proto_helper_{session_spec_proto_helper}, time_source_{time_source} {}

absl::StatusOr<BenchmarkResult> AdaptiveLoadControllerImpl::PerformAndAnalyzeNighthawkBenchmark(
    nighthawk::client::NighthawkService::StubInterface* nighthawk_service_stub,
    const AdaptiveLoadSessionSpec& spec,
    const absl::flat_hash_map<std::string, MetricsPluginPtr>& name_to_custom_plugin_map,
    StepController& step_controller, Envoy::ProtobufWkt::Duration duration) {
  absl::StatusOr<nighthawk::client::CommandLineOptions> command_line_options_or =
      step_controller.GetCurrentCommandLineOptions();
  if (!command_line_options_or.ok()) {
    ENVOY_LOG_MISC(error, "Error constructing Nighthawk input: {}: {}",
                   command_line_options_or.status().code(),
                   command_line_options_or.status().message());
    return command_line_options_or.status();
  }
  nighthawk::client::CommandLineOptions command_line_options = command_line_options_or.value();
  // Overwrite the duration in the traffic template with the specified duration of the adjusting
  // or testing stage.
  *command_line_options.mutable_duration() = std::move(duration);

  ENVOY_LOG_MISC(info, "Sending load: {}", command_line_options.DebugString());
  absl::StatusOr<nighthawk::client::ExecutionResponse> nighthawk_response_or =
      nighthawk_service_client_.PerformNighthawkBenchmark(nighthawk_service_stub,
                                                          command_line_options);
  if (!nighthawk_response_or.ok()) {
    ENVOY_LOG_MISC(error, "Nighthawk Service error: {}: {}", nighthawk_response_or.status().code(),
                   nighthawk_response_or.status().message());
    return nighthawk_response_or.status();
  }
  nighthawk::client::ExecutionResponse nighthawk_response = nighthawk_response_or.value();
  LogGlobalResultExcludingStatistics(nighthawk_response);

  absl::StatusOr<BenchmarkResult> benchmark_result_or =
      metrics_evaluator_.AnalyzeNighthawkBenchmark(nighthawk_response, spec,
                                                   name_to_custom_plugin_map);
  if (!benchmark_result_or.ok()) {
    ENVOY_LOG_MISC(error, "Benchmark scoring error: {}: {}", benchmark_result_or.status().code(),
                   benchmark_result_or.status().message());
    return benchmark_result_or.status();
  }
  BenchmarkResult benchmark_result = benchmark_result_or.value();
  for (const MetricEvaluation& evaluation : benchmark_result.metric_evaluations()) {
    ENVOY_LOG_MISC(info, "Evaluation: {}", evaluation.DebugString());
  }
  step_controller.UpdateAndRecompute(benchmark_result);
  return benchmark_result;
}

absl::StatusOr<AdaptiveLoadSessionOutput> AdaptiveLoadControllerImpl::PerformAdaptiveLoadSession(
    nighthawk::client::NighthawkService::StubInterface* nighthawk_service_stub,
    const AdaptiveLoadSessionSpec& input_spec) {
  AdaptiveLoadSessionSpec spec = session_spec_proto_helper_.SetSessionSpecDefaults(input_spec);
  absl::Status validation_status = session_spec_proto_helper_.CheckSessionSpec(spec);
  if (!validation_status.ok()) {
    ENVOY_LOG_MISC(error, "Validation failed: {}", validation_status.message());
    return validation_status;
  }
  absl::flat_hash_map<std::string, MetricsPluginPtr> name_to_custom_metrics_plugin_map =
      LoadMetricsPlugins(spec);
  StepControllerPtr step_controller = LoadStepControllerPluginFromSpec(spec);
  AdaptiveLoadSessionOutput output;

  // Threshold specs are reproduced in the output proto for convenience.
  for (const nighthawk::adaptive_load::MetricSpecWithThreshold& threshold :
       spec.metric_thresholds()) {
    *output.mutable_metric_thresholds()->Add() = threshold;
  }

  // Perform adjusting stage:
  Envoy::MonotonicTime start_time = time_source_.monotonicTime();
  std::string doom_reason;
  do {
    absl::StatusOr<BenchmarkResult> result_or = PerformAndAnalyzeNighthawkBenchmark(
        nighthawk_service_stub, spec, name_to_custom_metrics_plugin_map, *step_controller,
        spec.measuring_period());
    if (!result_or.ok()) {
      return result_or.status();
    }
    BenchmarkResult result = result_or.value();
    *output.mutable_adjusting_stage_results()->Add() = result;

    if (spec.has_benchmark_cooldown_duration()) {
      ENVOY_LOG_MISC(info, "Cooling down before the next benchmark for duration: {}",
                     spec.benchmark_cooldown_duration());
      uint64_t sleep_time_ms = Envoy::Protobuf::util::TimeUtil::DurationToMilliseconds(
          spec.benchmark_cooldown_duration());
      absl::SleepFor(absl::Milliseconds(sleep_time_ms));
    }

    const std::chrono::nanoseconds time_limit_ns(
        Envoy::Protobuf::util::TimeUtil::DurationToNanoseconds(spec.convergence_deadline()));
    const auto elapsed_time_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
        time_source_.monotonicTime() - start_time);
    if (elapsed_time_ns > time_limit_ns) {
      std::string message = absl::StrFormat("Failed to converge before deadline of %.2f seconds.",
                                            time_limit_ns.count() / 1e9);
      ENVOY_LOG_MISC(error, message);
      return absl::DeadlineExceededError(message);
    }
  } while (!step_controller->IsConverged() && !step_controller->IsDoomed(doom_reason));

  if (step_controller->IsDoomed(doom_reason)) {
    std::string message =
        absl::StrCat("Step controller determined that it can never converge: ", doom_reason);
    ENVOY_LOG_MISC(error, message);
    return absl::AbortedError(message);
  }

  // Perform testing stage:
  absl::StatusOr<BenchmarkResult> result_or = PerformAndAnalyzeNighthawkBenchmark(
      nighthawk_service_stub, spec, name_to_custom_metrics_plugin_map, *step_controller,
      spec.testing_stage_duration());
  if (!result_or.ok()) {
    return result_or.status();
  }
  *output.mutable_testing_stage_result() = result_or.value();
  return output;
}

} // namespace Nighthawk
<|endoftext|>