<commit_before>#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <sys/time.h>
#include <stdint.h>

using namespace std;
const int LOOP_COUNT = 100000;

static const uint8_t kBase64DecodeTable[256] ={
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0xff,0xff,0xff,0x3f,
0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xff,0xff,0xff,0xff,0xff,
0xff,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
};
static const uint8_t *kBase64EncodeTable = (const uint8_t *)
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

void  base64_encode(const uint8_t *in, uint32_t len, uint8_t *buf) {
  buf[0] = kBase64EncodeTable[(in[0] >> 2) & 0x3f];
  if (len == 3) {
    buf[1] = kBase64EncodeTable[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)];
    buf[2] = kBase64EncodeTable[((in[1] << 2) & 0x3c) | ((in[2] >> 6) & 0x03)];
    buf[3] = kBase64EncodeTable[in[2] & 0x3f];
  } else if (len == 2) {
    buf[1] = kBase64EncodeTable[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)];
    buf[2] = kBase64EncodeTable[(in[1] << 2) & 0x3c];
  } else  { // len == 1
    buf[1] = kBase64EncodeTable[(in[0] << 4) & 0x30];
  }
}

std::string Base64Encode(const std::string& src, std::string ending = "")
{
  uint8_t i = 0;
  uint8_t b[4];
  const uint8_t *bytes = (const uint8_t *) src.c_str();
  uint32_t len = src.length();

  std::stringstream ss;

  while (len >= 3)
  {
    base64_encode(bytes, 3, b);
    for (i = 0; i < 4; i++)
      ss << b[i];
    bytes += 3;
    len -= 3;
  }

  if (len > 0)
  {
    base64_encode(bytes, len, b);
    for (i = 0; i < len + 1; i++)
      ss << b[i];
  }

  ss << ending;

  return ss.str();
}

std::string Base64Encode1(const std::string& src, std::string ending = "")
{
  uint8_t i = 0;
  uint8_t b[4];
  const uint8_t *bytes = (const uint8_t *) src.c_str();
  uint32_t len = src.length();

  std::string s;

  while (len >= 3)
  {
    base64_encode(bytes, 3, b);
    for (i = 0; i < 4; i++)
      s += b[i];
    bytes += 3;
    len -= 3;
  }

  if (len > 0)
  {
    base64_encode(bytes, len, b);
    for (i = 0; i < len + 1; i++)
      s += b[i];
  }

  s += ending;

  return s;
}

int main(int argc, char *argv[])
{
  std::string s = "zqus387489tid'23	tck=e02fce03a933b5c8fffdf46442a2e8e9ts"
    "1461052882959uunid4tid=23&tck=e02fce03a933b5c8fffdf46442a2e8e9&ts=1461052882959&ver=1ip:106.39.88.82hostname:tf41dg.prod.mediav.comagent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4)"
    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36lang:en,zh-CN;q=0.8,zh;q=0.6,zh-TW;q=0.4referer:http://ckmap.mediav.com/b?type=10proxy:106.39.88.82, 202.79.203.111_mvctn191270=_mvsrc=118216_523698_1043440&_mvcam=191270_1241961_11970810_58740969_0&osr=oqdT0qhmgzj0&time=1449650466&rdom=anonymous; _mvctn165564=_mvsrc=118478_524001_1044112&_mvcam=165564_1224948_11775153_58841999_0&osr=Zg4c0cS49V00&time=1451040575&rdom=anonymous; v=)he((]^XdqB2fOE=[AjT; _jzqa=1.4336274511317232000.1447337529.1447337529.1461045516.2; _jzqc=1; _jzqckmp=1; ckmts=PUPtXAzi,P6PtXAzi,RGPtXAzi,R6PtXAzi,U6PtXAzi,JGPtXAzi,JrPtXAzi,J6PtXAzi,bUPtXAziver10:0|0:0|0:0|0:10p!"
    "version1.0";
  string a;
  struct timeval start, end;
  gettimeofday(&start, NULL);
  for (int i = 0; i < LOOP_COUNT; ++i)
  {
    a = Base64Encode(s);
  }
  gettimeofday(&end, NULL);
  std::cout << " timeuse: " << 1000000*(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) << std::endl;

  gettimeofday(&start, NULL);
  for (int i = 0; i < LOOP_COUNT; ++i)
  {
    a = Base64Encode1(s);
  }
  gettimeofday(&end, NULL);
  std::cout << " Base64Encode1 timeuse: " << 1000000*(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) << std::endl;
  return 0;
}
<commit_msg>temp commit<commit_after>#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <sys/time.h>
#include <stdint.h>

using namespace std;
const int LOOP_COUNT = 100000;

static const uint8_t kBase64DecodeTable[256] ={
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0xff,0xff,0xff,0x3f,
0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xff,0xff,0xff,0xff,0xff,
0xff,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
};
static const uint8_t *kBase64EncodeTable = (const uint8_t *)
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

void  base64_encode(const uint8_t *in, uint32_t len, uint8_t *buf) {
  buf[0] = kBase64EncodeTable[(in[0] >> 2) & 0x3f];
  if (len == 3) {
    buf[1] = kBase64EncodeTable[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)];
    buf[2] = kBase64EncodeTable[((in[1] << 2) & 0x3c) | ((in[2] >> 6) & 0x03)];
    buf[3] = kBase64EncodeTable[in[2] & 0x3f];
  } else if (len == 2) {
    buf[1] = kBase64EncodeTable[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)];
    buf[2] = kBase64EncodeTable[(in[1] << 2) & 0x3c];
  } else  { // len == 1
    buf[1] = kBase64EncodeTable[(in[0] << 4) & 0x30];
  }
}

std::string Base64Encode(const std::string& src, std::string ending = "")
{
  uint8_t i = 0;
  uint8_t b[4];
  const uint8_t *bytes = (const uint8_t *) src.c_str();
  uint32_t len = src.length();

  std::stringstream ss;

  while (len >= 3)
  {
    base64_encode(bytes, 3, b);
    for (i = 0; i < 4; i++)
      ss << b[i];
    bytes += 3;
    len -= 3;
  }

  if (len > 0)
  {
    base64_encode(bytes, len, b);
    for (i = 0; i < len + 1; i++)
      ss << b[i];
  }

  ss << ending;

  return ss.str();
}

std::string Base64Encode1(const std::string& src, std::string ending = "")
{
  uint8_t i = 0;
  uint8_t b[4];
  const uint8_t *bytes = (const uint8_t *) src.c_str();
  uint32_t len = src.length();

  std::string s;

  while (len >= 3)
  {
    base64_encode(bytes, 3, b);
    for (i = 0; i < 4; i++)
      s += b[i];
    bytes += 3;
    len -= 3;
  }

  if (len > 0)
  {
    base64_encode(bytes, len, b);
    for (i = 0; i < len + 1; i++)
      s += b[i];
  }

  s += ending;

  return s;
}

int main(int argc, char *argv[])
{
  std::string s = "zqus387489tid'23	tck=e02fce03a933b5c8fffdf46442a2e8e9ts"
    "1461052882959uunid4tid=23&tck=e02fce03a933b5c8fffdf46442a2e8e9&ts=1461052882959&ver=1ip:106.39.88.82hostname:tf41dg.prod.mediav.comagent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4)"
    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36lang:en,zh-CN;q=0.8,zh;q=0.6,zh-TW;q=0.4referer:http://ckmap.mediav.com/b?type=10proxy:106.39.88.82, 202.79.203.111_mvctn191270=_mvsrc=118216_523698_1043440&_mvcam=191270_1241961_11970810_58740969_0&osr=oqdT0qhmgzj0&time=1449650466&rdom=anonymous; _mvctn165564=_mvsrc=118478_524001_1044112&_mvcam=165564_1224948_11775153_58841999_0&osr=Zg4c0cS49V00&time=1451040575&rdom=anonymous; v=)he((]^XdqB2fOE=[AjT; _jzqa=1.4336274511317232000.1447337529.1447337529.1461045516.2; _jzqc=1; _jzqckmp=1; ckmts=PUPtXAzi,P6PtXAzi,RGPtXAzi,R6PtXAzi,U6PtXAzi,JGPtXAzi,JrPtXAzi,J6PtXAzi,bUPtXAziver10:0|0:0|0:0|0:10p!"
    "version1.0";
  string a;
  struct timeval start, end;
  gettimeofday(&start, NULL);
  for (int i = 0; i < LOOP_COUNT; ++i)
  {
    a = Base64Encode(s);
  }
  std::cout << "base64encoded: " << a << std::endl;
  gettimeofday(&end, NULL);
  std::cout << "Base64Encode timeuse: " << 1000000*(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) << std::endl;

  gettimeofday(&start, NULL);
  for (int i = 0; i < LOOP_COUNT; ++i)
  {
    a = Base64Encode1(s);
  }
  std::cout << "base64encoded: " << a << std::endl;
  gettimeofday(&end, NULL);
  std::cout << " Base64Encode1 timeuse: " << 1000000*(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) << std::endl;
  return 0;
}
<|endoftext|>


<commit_before>#include "gtest/gtest.h"

#include "TH1.h"
#include "ROOT/v7/TH1.h"

// Tests the number of bins
TEST(AxisTest, NumBins) {
  EXPECT_EQ(0, 0);
}

// Tests the axis range
TEST(AxisTest, RangeFromTo) {
  EXPECT_EQ(1, 1);
}
<commit_msg>Fix include.<commit_after>#include "gtest/gtest.h"

#include "TH1.h"
#include "ROOT/THist.h"

// Tests the number of bins
TEST(AxisTest, NumBins) {
  EXPECT_EQ(0, 0);
}

// Tests the axis range
TEST(AxisTest, RangeFromTo) {
  EXPECT_EQ(1, 1);
}
<|endoftext|>


<commit_before>/* medRunnableProcess.cpp ---
 *
 * Author: Julien Wintz
 * Copyright (C) 2008 - Julien Wintz, Inria.
 * Created: Tue Dec 15 09:40:14 2009 (+0100)
 * Version: $Id$
 * Last-Updated: Tue Dec 15 09:40:15 2009 (+0100)
 *           By: Julien Wintz
 *     Update #: 1
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "medRunnableProcess.h"

#include <dtkCore/dtkAbstractProcess.h>

class medRunnableProcessPrivate
{
public:
    dtkAbstractProcess *process;
};

medRunnableProcess::medRunnableProcess(void): medJobItem(), d (new medRunnableProcessPrivate)
{
    d->process = 0;
}

medRunnableProcess::~medRunnableProcess (void)
{
    delete d;
    d = NULL;
}

void medRunnableProcess::setProcess (dtkAbstractProcess *proc)
{
    d->process = proc;

    if (d->process) {
	connect (d->process, SIGNAL (success()),       this, SLOT (onSuccess()),       Qt::BlockingQueuedConnection);
	connect (d->process, SIGNAL (failure()),       this, SLOT (onFailure()),       Qt::BlockingQueuedConnection);
	connect (d->process, SIGNAL (progressed(int)), this, SLOT (onProgressed(int)), Qt::QueuedConnection);
    }
}

void medRunnableProcess::run (void)
{
    if (d->process) {
        d->process->run();
    }
}

void medRunnableProcess::onSuccess (void)
{
    emit success (this);
}

void medRunnableProcess::onFailure (void)
{
    emit failure (this);
}

void medRunnableProcess::onProgressed (int value)
{
    emit progressed (this, value);
}

void medRunnableProcess::onCancel (QObject *sender)
{
    if (d->process) {
        d->process->cancel();
    }

    emit (cancelled (this));
}
<commit_msg>Do not translate signals from process to jobs. Instead, emit those in the run() method.<commit_after>/* medRunnableProcess.cpp ---
 *
 * Author: Julien Wintz
 * Copyright (C) 2008 - Julien Wintz, Inria.
 * Created: Tue Dec 15 09:40:14 2009 (+0100)
 * Version: $Id$
 * Last-Updated: Tue Dec 15 09:40:15 2009 (+0100)
 *           By: Julien Wintz
 *     Update #: 1
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "medRunnableProcess.h"

#include <dtkCore/dtkAbstractProcess.h>

class medRunnableProcessPrivate
{
public:
    dtkAbstractProcess *process;
};

medRunnableProcess::medRunnableProcess(void): medJobItem(), d (new medRunnableProcessPrivate)
{
    d->process = 0;
}

medRunnableProcess::~medRunnableProcess (void)
{
    delete d;
    d = NULL;
}

void medRunnableProcess::setProcess (dtkAbstractProcess *proc)
{
    d->process = proc;

    if (d->process) {
        // QueuedConnection does not seem to work (never called). Changing it to BlockingQueuedConnection
        // may result in a dead lock. Then, it is better to emit those directly from the run() method.
        // connect (d->process, SIGNAL (success()),       this, SLOT (onSuccess()), Qt::QueuedConnection);
        // connect (d->process, SIGNAL (failure()),       this, SLOT (onFailure()), Qt::QueuedConnection);
	connect (d->process, SIGNAL (progressed(int)), this, SLOT (onProgressed(int)), Qt::QueuedConnection);
    }
}

void medRunnableProcess::run (void)
{
    if (d->process) {
        if (d->process->update()==0)
	    emit success (this);
	else
	    emit failure (this);
    }
}

void medRunnableProcess::onSuccess (void)
{
    emit success (this);
}

void medRunnableProcess::onFailure (void)
{
    emit failure (this);
}

void medRunnableProcess::onProgressed (int value)
{
    emit progressed (this, value);
}

void medRunnableProcess::onCancel (QObject *sender)
{
    if (d->process) {
        d->process->onCanceled();
    }

    emit (cancelled (this));
}
<|endoftext|>


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

#include <chrono>

#include "catch.hpp"
#include "helpers.hpp"

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/document/view.hpp>
#include <mongocxx/exception/logic_error.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/options/find.hpp>

using namespace bsoncxx::builder::stream;
using namespace mongocxx;

TEST_CASE("find", "[find][option]") {
    instance::current();

    options::find find_opts{};

    auto collation = document{} << "locale"
                                << "en_US" << finalize;
    auto max = document{} << "a" << 6 << finalize;
    auto min = document{} << "a" << 3 << finalize;
    auto modifiers = document{} << "$comment"
                                << "comment" << finalize;
    auto projection = document{} << "_id" << false << finalize;
    auto sort = document{} << "x" << -1 << finalize;

    CHECK_OPTIONAL_ARGUMENT(find_opts, allow_partial_results, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, batch_size, 3);
    CHECK_OPTIONAL_ARGUMENT(find_opts, collation, collation.view());
    CHECK_OPTIONAL_ARGUMENT(find_opts, comment, "comment");
    CHECK_OPTIONAL_ARGUMENT(find_opts, cursor_type, cursor::type::k_non_tailable);
    CHECK_OPTIONAL_ARGUMENT(find_opts, limit, 3);
    CHECK_OPTIONAL_ARGUMENT(find_opts, max, max.view());
    CHECK_OPTIONAL_ARGUMENT(find_opts, max_await_time, std::chrono::milliseconds{300});
    CHECK_OPTIONAL_ARGUMENT(find_opts, max_scan, 3);
    CHECK_OPTIONAL_ARGUMENT(find_opts, max_time, std::chrono::milliseconds{300});
    CHECK_OPTIONAL_ARGUMENT(find_opts, min, min.view());
    CHECK_OPTIONAL_ARGUMENT(find_opts, modifiers, modifiers.view());
    CHECK_OPTIONAL_ARGUMENT(find_opts, no_cursor_timeout, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, projection, projection.view());
    CHECK_OPTIONAL_ARGUMENT_WITHOUT_EQUALITY(find_opts, read_preference, read_preference{});
    CHECK_OPTIONAL_ARGUMENT(find_opts, return_key, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, show_record_id, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, skip, 3);
    CHECK_OPTIONAL_ARGUMENT(find_opts, snapshot, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, sort, sort.view());
}
<commit_msg>CXX-1051 Add test coverage for options::find::hint()<commit_after>// Copyright 2016 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <chrono>

#include "catch.hpp"
#include "helpers.hpp"

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/document/view.hpp>
#include <mongocxx/exception/logic_error.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/options/find.hpp>

using namespace bsoncxx::builder::stream;
using namespace mongocxx;

TEST_CASE("find", "[find][option]") {
    instance::current();

    options::find find_opts{};

    auto collation = document{} << "locale"
                                << "en_US" << finalize;
    auto hint = bsoncxx::document::view_or_value{document{} << "_id" << 1 << finalize};
    auto max = document{} << "a" << 6 << finalize;
    auto min = document{} << "a" << 3 << finalize;
    auto modifiers = document{} << "$comment"
                                << "comment" << finalize;
    auto projection = document{} << "_id" << false << finalize;
    auto sort = document{} << "x" << -1 << finalize;

    CHECK_OPTIONAL_ARGUMENT(find_opts, allow_partial_results, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, batch_size, 3);
    CHECK_OPTIONAL_ARGUMENT(find_opts, collation, collation.view());
    CHECK_OPTIONAL_ARGUMENT(find_opts, comment, "comment");
    CHECK_OPTIONAL_ARGUMENT(find_opts, cursor_type, cursor::type::k_non_tailable);
    CHECK_OPTIONAL_ARGUMENT(find_opts, hint, hint);
    CHECK_OPTIONAL_ARGUMENT(find_opts, limit, 3);
    CHECK_OPTIONAL_ARGUMENT(find_opts, max, max.view());
    CHECK_OPTIONAL_ARGUMENT(find_opts, max_await_time, std::chrono::milliseconds{300});
    CHECK_OPTIONAL_ARGUMENT(find_opts, max_scan, 3);
    CHECK_OPTIONAL_ARGUMENT(find_opts, max_time, std::chrono::milliseconds{300});
    CHECK_OPTIONAL_ARGUMENT(find_opts, min, min.view());
    CHECK_OPTIONAL_ARGUMENT(find_opts, modifiers, modifiers.view());
    CHECK_OPTIONAL_ARGUMENT(find_opts, no_cursor_timeout, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, projection, projection.view());
    CHECK_OPTIONAL_ARGUMENT_WITHOUT_EQUALITY(find_opts, read_preference, read_preference{});
    CHECK_OPTIONAL_ARGUMENT(find_opts, return_key, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, show_record_id, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, skip, 3);
    CHECK_OPTIONAL_ARGUMENT(find_opts, snapshot, true);
    CHECK_OPTIONAL_ARGUMENT(find_opts, sort, sort.view());
}
<|endoftext|>


<commit_before>#include "stochastic.h"
#include "accumulator.h"
#include "sampler.h"
#include "file/logger.h"
#include "util/log_search.hpp"
#include "util/thread_pool.h"
#include "util/timer.h"
#include "optimize.h"

namespace ncv
{
        namespace detail
        {
                static opt_state_t tune(
                        trainer_data_t& data,
                        stochastic_optimizer optimizer, scalar_t alpha0, scalar_t decay)
                {
                        const size_t epochs = 1;

                        // construct the optimization problem (NB: one random sample at the time)
                        auto fn_size = ncv::make_opsize(data);
                        auto fn_fval = ncv::make_opfval(data);
                        auto fn_grad = ncv::make_opgrad(data);

                        auto fn_wlog = nullptr;
                        auto fn_elog = nullptr;
                        auto fn_ulog = nullptr;

                        // assembly optimization problem & optimize the model
                        opt_state_t opt = ncv::minimize(
                                fn_size, fn_fval, fn_grad, fn_wlog, fn_elog, fn_ulog,
                                data.m_x0, optimizer, epochs, data.m_tsampler.size(), alpha0, decay);

                        // OK, cumulate the loss value
                        data.m_lacc.reset(opt.x);
                        data.m_lacc.update(data.m_task, data.m_tsampler.all(), data.m_loss);

                        opt.f = data.m_lacc.value();
                        return opt;
                }

                static trainer_result_t train(
                        trainer_data_t& data,
                        stochastic_optimizer optimizer, size_t epochs, scalar_t alpha0, scalar_t decay,
                        thread_pool_t::mutex_t& mutex)
                {
                        trainer_result_t result;

                        const ncv::timer_t timer;

                        // construct the optimization problem (NB: one random sample at the time)
                        size_t epoch = 0;

                        auto fn_size = ncv::make_opsize(data);
                        auto fn_fval = ncv::make_opfval(data);
                        auto fn_grad = ncv::make_opgrad(data);

                        auto fn_wlog = ncv::make_opwlog();
                        auto fn_elog = ncv::make_opelog();
                        auto fn_ulog = [&] (const opt_state_t& state)
                        {
                                // evaluate training samples
                                data.m_lacc.reset(state.x);
                                data.m_lacc.update(data.m_task, data.m_tsampler.all(), data.m_loss);
                                const scalar_t tvalue = data.m_lacc.value();
                                const scalar_t terror_avg = data.m_lacc.avg_error();
                                const scalar_t terror_var = data.m_lacc.var_error();

                                // evaluate validation samples
                                data.m_lacc.reset(state.x);
                                data.m_lacc.update(data.m_task, data.m_vsampler.all(), data.m_loss);
                                const scalar_t vvalue = data.m_lacc.value();
                                const scalar_t verror_avg = data.m_lacc.avg_error();
                                const scalar_t verror_var = data.m_lacc.var_error();

                                epoch ++;

                                // OK, update the optimum solution
                                const thread_pool_t::lock_t lock(mutex);

                                result.update(state.x, tvalue, terror_avg, terror_var, vvalue, verror_avg, verror_var,
                                              epoch, scalars_t({ alpha0, decay, data.m_lacc.lambda() }));

                                log_info()
                                << "[train = " << tvalue << "/" << terror_avg
                                << ", valid = " << vvalue << "/" << verror_avg
                                << ", xnorm = " << state.x.lpNorm<Eigen::Infinity>()
                                << ", alpha = " << alpha0
                                << ", decay = " << decay
                                << ", epoch = " << epoch << "/" << epochs
                                << ", lambda = " << data.m_lacc.lambda()
                                << "] done in " << timer.elapsed() << ".";
                        };

                        // assembly optimization problem & optimize the model
                        ncv::minimize(fn_size, fn_fval, fn_grad, fn_wlog, fn_elog, fn_ulog,
                                      data.m_x0, optimizer, epochs, data.m_tsampler.size(), alpha0, decay);

                        // OK
                        return result;
                }
        }

        trainer_result_t stochastic_train(
                const model_t& model, const task_t& task, const sampler_t& tsampler, const sampler_t& vsampler, size_t nthreads,
                const loss_t& loss, const string_t& criterion,
                stochastic_optimizer optimizer, size_t epochs)
        {
                thread_pool_t::mutex_t mutex;

                // operator to train for a given regularization factor
                const auto op = [&] (scalar_t lambda)
                {
                        vector_t x0;
                        model.save_params(x0);

                        opt_state_t opt_state;
                        scalar_t opt_alpha = 1.00;
                        scalar_t opt_decay = 0.50;

                        // operator to tune the learning rate
                        const auto op_lrate = [&] (scalar_t alpha)
                        {
                                accumulator_t lacc(model, 1, criterion, criterion_t::type::value, lambda);
                                accumulator_t gacc(model, 1, criterion, criterion_t::type::vgrad, lambda);

                                trainer_data_t data(task, tsampler, vsampler, loss, x0, lacc, gacc);

                                // also tune the decay rate (if possible)
                                const scalars_t decays = (optimizer == stochastic_optimizer::NAG) ?
                                        scalars_t({ 1.00 }) :
                                        scalars_t({ 0.0, 0.10, 0.20, 0.50, 0.75, 1.00 });

                                std::set<std::pair<opt_state_t, scalar_t> > states;
                                for (scalar_t decay : decays)
                                {
                                        const ncv::timer_t timer;

                                        const opt_state_t state = detail::tune(data, optimizer, alpha, decay);

                                        const thread_pool_t::lock_t lock(mutex);

                                        log_info()
                                                << "[tuning: loss = " << state.f
                                                << ", alpha = " << alpha
                                                << ", decay = " << decay
                                                << ", lambda = " << data.m_lacc.lambda()
                                                << "] done in " << timer.elapsed() << ".";

                                        states.insert(std::make_pair(state, decay));
                                }

                                if (states.begin()->first < opt_state)
                                {
                                        opt_state = states.begin()->first;
                                        opt_alpha = alpha;
                                        opt_decay = states.begin()->second;
                                }

                                return states.begin()->first;
                        };

                        log10_min_search(op_lrate, -4.0, +2.0, 0.2, 4);

                        // train the model using the tuned learning rate & decay rate
                        {
                                accumulator_t lacc(model, 1, criterion, criterion_t::type::value, lambda);
                                accumulator_t gacc(model, 1, criterion, criterion_t::type::vgrad, lambda);

                                trainer_data_t data(task, tsampler, vsampler, loss, x0, lacc, gacc);

                                return detail::train(data, optimizer, epochs, opt_alpha, opt_decay, mutex);
                        }
                };

                // tune the regularization factor (if needed)
                if (accumulator_t::can_regularize(criterion))
                {
                        thread_pool_t wpool(nthreads);
                        return log10_min_search_mt(op, wpool, -4.0, +4.0, 0.5, nthreads).first;
                }

                else
                {
                        return op(0.0);
                }
        }
}
<commit_msg>MT the learning rate (if no regularizer)<commit_after>#include "stochastic.h"
#include "accumulator.h"
#include "sampler.h"
#include "file/logger.h"
#include "util/log_search.hpp"
#include "util/thread_pool.h"
#include "util/timer.h"
#include "optimize.h"

namespace ncv
{
        namespace detail
        {
                static opt_state_t tune(
                        trainer_data_t& data,
                        stochastic_optimizer optimizer, scalar_t alpha0, scalar_t decay)
                {
                        const size_t epochs = 1;

                        // construct the optimization problem (NB: one random sample at the time)
                        auto fn_size = ncv::make_opsize(data);
                        auto fn_fval = ncv::make_opfval(data);
                        auto fn_grad = ncv::make_opgrad(data);

                        auto fn_wlog = nullptr;
                        auto fn_elog = nullptr;
                        auto fn_ulog = nullptr;

                        // assembly optimization problem & optimize the model
                        opt_state_t opt = ncv::minimize(
                                fn_size, fn_fval, fn_grad, fn_wlog, fn_elog, fn_ulog,
                                data.m_x0, optimizer, epochs, data.m_tsampler.size(), alpha0, decay);

                        // OK, cumulate the loss value
                        data.m_lacc.reset(opt.x);
                        data.m_lacc.update(data.m_task, data.m_tsampler.all(), data.m_loss);

                        opt.f = data.m_lacc.value();
                        return opt;
                }

                static trainer_result_t train(
                        trainer_data_t& data,
                        stochastic_optimizer optimizer, size_t epochs, scalar_t alpha0, scalar_t decay,
                        thread_pool_t::mutex_t& mutex)
                {
                        trainer_result_t result;

                        const ncv::timer_t timer;

                        // construct the optimization problem (NB: one random sample at the time)
                        size_t epoch = 0;

                        auto fn_size = ncv::make_opsize(data);
                        auto fn_fval = ncv::make_opfval(data);
                        auto fn_grad = ncv::make_opgrad(data);

                        auto fn_wlog = ncv::make_opwlog();
                        auto fn_elog = ncv::make_opelog();
                        auto fn_ulog = [&] (const opt_state_t& state)
                        {
                                // evaluate training samples
                                data.m_lacc.reset(state.x);
                                data.m_lacc.update(data.m_task, data.m_tsampler.all(), data.m_loss);
                                const scalar_t tvalue = data.m_lacc.value();
                                const scalar_t terror_avg = data.m_lacc.avg_error();
                                const scalar_t terror_var = data.m_lacc.var_error();

                                // evaluate validation samples
                                data.m_lacc.reset(state.x);
                                data.m_lacc.update(data.m_task, data.m_vsampler.all(), data.m_loss);
                                const scalar_t vvalue = data.m_lacc.value();
                                const scalar_t verror_avg = data.m_lacc.avg_error();
                                const scalar_t verror_var = data.m_lacc.var_error();

                                epoch ++;

                                // OK, update the optimum solution
                                const thread_pool_t::lock_t lock(mutex);

                                result.update(state.x, tvalue, terror_avg, terror_var, vvalue, verror_avg, verror_var,
                                              epoch, scalars_t({ alpha0, decay, data.m_lacc.lambda() }));

                                log_info()
                                << "[train = " << tvalue << "/" << terror_avg
                                << ", valid = " << vvalue << "/" << verror_avg
                                << ", xnorm = " << state.x.lpNorm<Eigen::Infinity>()
                                << ", alpha = " << alpha0
                                << ", decay = " << decay
                                << ", epoch = " << epoch << "/" << epochs
                                << ", lambda = " << data.m_lacc.lambda()
                                << "] done in " << timer.elapsed() << ".";
                        };

                        // assembly optimization problem & optimize the model
                        ncv::minimize(fn_size, fn_fval, fn_grad, fn_wlog, fn_elog, fn_ulog,
                                      data.m_x0, optimizer, epochs, data.m_tsampler.size(), alpha0, decay);

                        // OK
                        return result;
                }
        }

        trainer_result_t stochastic_train(
                const model_t& model, const task_t& task, const sampler_t& tsampler, const sampler_t& vsampler, size_t nthreads,
                const loss_t& loss, const string_t& criterion,
                stochastic_optimizer optimizer, size_t epochs)
        {
                thread_pool_t::mutex_t mutex;

                // operator to train for a given regularization factor
                const auto op = [&] (scalar_t lambda)
                {
                        vector_t x0;
                        model.save_params(x0);

                        opt_state_t opt_state;
                        scalar_t opt_alpha = 1.00;
                        scalar_t opt_decay = 0.50;

                        // operator to tune the learning rate
                        const auto op_lrate = [&] (scalar_t alpha)
                        {
                                accumulator_t lacc(model, 1, criterion, criterion_t::type::value, lambda);
                                accumulator_t gacc(model, 1, criterion, criterion_t::type::vgrad, lambda);

                                trainer_data_t data(task, tsampler, vsampler, loss, x0, lacc, gacc);

                                // also tune the decay rate (if possible)
                                const scalars_t decays = (optimizer == stochastic_optimizer::NAG) ?
                                        scalars_t({ 1.00 }) :
                                        scalars_t({ 0.0, 0.10, 0.20, 0.50, 0.75, 1.00 });

                                std::set<std::pair<opt_state_t, scalar_t> > states;
                                for (scalar_t decay : decays)
                                {
                                        const ncv::timer_t timer;

                                        const opt_state_t state = detail::tune(data, optimizer, alpha, decay);

                                        const thread_pool_t::lock_t lock(mutex);

                                        log_info()
                                                << "[tuning: loss = " << state.f
                                                << ", alpha = " << alpha
                                                << ", decay = " << decay
                                                << ", lambda = " << data.m_lacc.lambda()
                                                << "] done in " << timer.elapsed() << ".";

                                        states.insert(std::make_pair(state, decay));
                                }

                                if (states.begin()->first < opt_state)
                                {
                                        opt_state = states.begin()->first;
                                        opt_alpha = alpha;
                                        opt_decay = states.begin()->second;
                                }

                                return states.begin()->first;
                        };

                        if (accumulator_t::can_regularize(criterion))
                        {
                                // single-thread tuning
                                log10_min_search(op_lrate, -4.0, +2.0, 0.2, 4);
                        }

                        else
                        {
                                // multi-thread tuning
                                thread_pool_t wpool(nthreads);
                                log10_min_search_mt(op_lrate, wpool, -4.0, +2.0, 0.2, wpool.n_workers());
                        }

                        // train the model using the tuned learning rate & decay rate
                        {
                                accumulator_t lacc(model, 1, criterion, criterion_t::type::value, lambda);
                                accumulator_t gacc(model, 1, criterion, criterion_t::type::vgrad, lambda);

                                trainer_data_t data(task, tsampler, vsampler, loss, x0, lacc, gacc);

                                return detail::train(data, optimizer, epochs, opt_alpha, opt_decay, mutex);
                        }
                };

                // tune the regularization factor (if needed)
                if (accumulator_t::can_regularize(criterion))
                {
                        thread_pool_t wpool(nthreads);
                        return log10_min_search_mt(op, wpool, -4.0, +4.0, 0.5, wpool.n_workers()).first;
                }

                else
                {
                        return op(0.0);
                }
        }
}
<|endoftext|>


<commit_before>/*
    emoticonselector.cpp

    a button that pops up a list of all emoticons and returns
    the emoticon-string if one is selected in the list

    Copyright (c) 2002      by Stefan Gehn            <metz@gehn.net>
    Copyright (c) 2003      by Martijn Klingens       <klingens@kde.org>

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "emoticonselector.h"
#include "kopeteemoticons.h"

#include <math.h>

#include <QPixmap>
#include <QMouseEvent>
#include <QHBoxLayout>
#include <QObject>
#include <QHideEvent>
#include <QShowEvent>

#include <kdebug.h>
#include <kemoticons.h>

EmoticonItem::EmoticonItem(const QString &emoticonText, const QString &pixmapPath, QListWidget *parent)
	: QListWidgetItem(parent)
{
	m_text = emoticonText;
	m_pixmapPath = pixmapPath;
	QPixmap p(m_pixmapPath);
    //
    // Some of the custom icons are rather large
    // so lets limit them to a maximum size for this display panel
    //
    if (p.width() > 32 || p.height() > 32)
		p = p.scaled(QSize(32,32), Qt::KeepAspectRatio);

	setIcon(p);
}

QString EmoticonItem::text() const
{
	return m_text;
}

QString EmoticonItem::pixmapPath() const
{
	return m_pixmapPath;
}

EmoticonSelector::EmoticonSelector(QWidget *parent)
	: QWidget(parent)
{
	QHBoxLayout *lay = new QHBoxLayout(this);
	lay->setSpacing( 0 );
	lay->setContentsMargins( 0, 0, 0, 0 );
	m_emoticonList = new QListWidget(this);
	lay->addWidget(m_emoticonList);
	m_emoticonList->setViewMode(QListView::IconMode);
	m_emoticonList->setSelectionMode(QAbstractItemView::SingleSelection);
	m_emoticonList->setMouseTracking(true);
	m_emoticonList->setDragEnabled(false);

	QLabel *m_currentEmoticon  = new QLabel( this );
	m_currentEmoticon->setFrameShape( QFrame::Box );
	m_currentEmoticon->setMinimumSize(QSize(128,128));
	m_currentEmoticon->setAlignment( Qt::AlignCenter );
	lay->addWidget(m_currentEmoticon);

	m_currentMovie = new QMovie(this);
	m_currentEmoticon->setMovie(m_currentMovie);

	connect(m_emoticonList, SIGNAL(itemEntered(QListWidgetItem*)),
			this, SLOT(mouseOverItem(QListWidgetItem*)));
	connect(m_emoticonList, SIGNAL(itemSelectionChanged()),
			this, SLOT(currentChanged()));
	connect(m_emoticonList, SIGNAL(itemClicked(QListWidgetItem*)),
			this, SLOT(emoticonClicked(QListWidgetItem*)));

	connect(m_emoticonList, SIGNAL(itemActivated(QListWidgetItem*)),
			this, SLOT(emoticonClicked(QListWidgetItem*)));

}

void EmoticonSelector::prepareList(void)
{
	m_emoticonList->clear();
//	kDebug(14000) << "called.";
	QHash<QString, QStringList> list = Kopete::Emoticons::self()->theme().emoticonsMap();

	for (QHash<QString, QStringList>::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
		(void) new EmoticonItem(it.value().first(), it.key(), m_emoticonList);

	m_emoticonList->setIconSize(QSize(32,32));
}

void EmoticonSelector::emoticonClicked(QListWidgetItem *i)
{
	EmoticonItem *item = dynamic_cast<EmoticonItem*>(i);
	if (!item)
		return;

	// KDE4/Qt TODO: use qobject_cast instead.
	emit itemSelected ( item->text() );
	if ( isVisible() && parentWidget() &&
		parentWidget()->inherits("QMenu") )
	{
		parentWidget()->close();
	}
}

void EmoticonSelector::mouseOverItem(QListWidgetItem *item)
{
	item->setSelected(true);
	if (!m_emoticonList->hasFocus())
		m_emoticonList->setFocus();
}

void EmoticonSelector::currentChanged()
{

	if (!m_emoticonList->selectedItems().count())
		return;

	EmoticonItem *item = dynamic_cast<EmoticonItem*>(m_emoticonList->selectedItems().first());
	if (!item)
		return;

	// FIXME: the label is not correctly cleared when changing from a bigger movie to a smaller one
	m_currentMovie->stop();
	m_currentMovie->setFileName(item->pixmapPath());
	m_currentMovie->start();
}

void EmoticonSelector::hideEvent( QHideEvent* )
{
	m_currentMovie->stop();
}

void EmoticonSelector::showEvent( QShowEvent* )
{
	m_currentMovie->start();
}

#include "emoticonselector.moc"

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>Don't connect both clicked and activated, that will trigger the action twice. BUG: 165900<commit_after>/*
    emoticonselector.cpp

    a button that pops up a list of all emoticons and returns
    the emoticon-string if one is selected in the list

    Copyright (c) 2002      by Stefan Gehn            <metz@gehn.net>
    Copyright (c) 2003      by Martijn Klingens       <klingens@kde.org>

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "emoticonselector.h"
#include "kopeteemoticons.h"

#include <math.h>

#include <QPixmap>
#include <QMouseEvent>
#include <QHBoxLayout>
#include <QObject>
#include <QHideEvent>
#include <QShowEvent>

#include <kdebug.h>
#include <kemoticons.h>

EmoticonItem::EmoticonItem(const QString &emoticonText, const QString &pixmapPath, QListWidget *parent)
	: QListWidgetItem(parent)
{
	m_text = emoticonText;
	m_pixmapPath = pixmapPath;
	QPixmap p(m_pixmapPath);
    //
    // Some of the custom icons are rather large
    // so lets limit them to a maximum size for this display panel
    //
    if (p.width() > 32 || p.height() > 32)
		p = p.scaled(QSize(32,32), Qt::KeepAspectRatio);

	setIcon(p);
}

QString EmoticonItem::text() const
{
	return m_text;
}

QString EmoticonItem::pixmapPath() const
{
	return m_pixmapPath;
}

EmoticonSelector::EmoticonSelector(QWidget *parent)
	: QWidget(parent)
{
	QHBoxLayout *lay = new QHBoxLayout(this);
	lay->setSpacing( 0 );
	lay->setContentsMargins( 0, 0, 0, 0 );
	m_emoticonList = new QListWidget(this);
	lay->addWidget(m_emoticonList);
	m_emoticonList->setViewMode(QListView::IconMode);
	m_emoticonList->setSelectionMode(QAbstractItemView::SingleSelection);
	m_emoticonList->setMouseTracking(true);
	m_emoticonList->setDragEnabled(false);

	QLabel *m_currentEmoticon  = new QLabel( this );
	m_currentEmoticon->setFrameShape( QFrame::Box );
	m_currentEmoticon->setMinimumSize(QSize(128,128));
	m_currentEmoticon->setAlignment( Qt::AlignCenter );
	lay->addWidget(m_currentEmoticon);

	m_currentMovie = new QMovie(this);
	m_currentEmoticon->setMovie(m_currentMovie);

	connect(m_emoticonList, SIGNAL(itemEntered(QListWidgetItem*)),
			this, SLOT(mouseOverItem(QListWidgetItem*)));
	connect(m_emoticonList, SIGNAL(itemSelectionChanged()),
			this, SLOT(currentChanged()));
	connect(m_emoticonList, SIGNAL(itemActivated(QListWidgetItem*)),
			this, SLOT(emoticonClicked(QListWidgetItem*)));

}

void EmoticonSelector::prepareList(void)
{
	m_emoticonList->clear();
//	kDebug(14000) << "called.";
	QHash<QString, QStringList> list = Kopete::Emoticons::self()->theme().emoticonsMap();

	for (QHash<QString, QStringList>::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
		(void) new EmoticonItem(it.value().first(), it.key(), m_emoticonList);

	m_emoticonList->setIconSize(QSize(32,32));
}

void EmoticonSelector::emoticonClicked(QListWidgetItem *i)
{
	EmoticonItem *item = dynamic_cast<EmoticonItem*>(i);
	if (!item)
		return;

	// KDE4/Qt TODO: use qobject_cast instead.
	emit itemSelected ( item->text() );
	if ( isVisible() && parentWidget() &&
		parentWidget()->inherits("QMenu") )
	{
		parentWidget()->close();
	}
}

void EmoticonSelector::mouseOverItem(QListWidgetItem *item)
{
	item->setSelected(true);
	if (!m_emoticonList->hasFocus())
		m_emoticonList->setFocus();
}

void EmoticonSelector::currentChanged()
{

	if (!m_emoticonList->selectedItems().count())
		return;

	EmoticonItem *item = dynamic_cast<EmoticonItem*>(m_emoticonList->selectedItems().first());
	if (!item)
		return;

	// FIXME: the label is not correctly cleared when changing from a bigger movie to a smaller one
	m_currentMovie->stop();
	m_currentMovie->setFileName(item->pixmapPath());
	m_currentMovie->start();
}

void EmoticonSelector::hideEvent( QHideEvent* )
{
	m_currentMovie->stop();
}

void EmoticonSelector::showEvent( QShowEvent* )
{
	m_currentMovie->start();
}

#include "emoticonselector.moc"

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>


<commit_before>#include <config.h>

#ifdef VJ_OS_HPUX
#   include <algorithm>
#else
#   if defined(VJ_USE_PTHREADS) && ! defined(_PTHREADS)
#       define _PTHREADS
#   endif

#   include <algo.h>
#endif

#include <Kernel/GL/vjGlPipe.h>
#include <Threads/vjThread.h>
#include <Sync/vjGuard.h>
#include <Kernel/vjDebug.h>

/** Start the pipe running
 * POST: The pipe has it's own thread of control and is ready to operate
 */
int vjGlPipe::start()
{
   vjASSERT(mThreadRunning == false);        // We should not be running yet

   // Create a new thread to handle the control loop
   vjThreadId* controlPid;

   vjThreadMemberFunctor<vjGlPipe>* memberFunctor =
   new vjThreadMemberFunctor<vjGlPipe>(this, &vjGlPipe::controlLoop, NULL);

   controlPid = vjThread::spawn(memberFunctor, 0);

   cerr << "vjGlPipe::start: Started control loop.  " << *controlPid << endl;
   return 1;
}

/** Trigger rendering of the pipe to start
 * POST: The pipe has be told to start rendering
 */
void vjGlPipe::triggerRender()
{
   vjASSERT(mThreadRunning == true);      // We must be running

   renderCond.acquire();
   {
      renderState = RENDERING;
      renderCond.signal();
   }
   renderCond.release();
}

/** Blocks until rendering of the windows is completed
 * POST: The pipe has completed its rendering
 */
void vjGlPipe::completeRender()
{
   vjASSERT(mThreadRunning == true);      // We must be running

   renderCond.acquire();
   {        // Wait for renderState == WAITING
      while (renderState != WAITING)
         renderCond.wait();
      /* Do nothing */
   }
   renderCond.release();
}

/// Add a GLWindow to the window list
// Control loop must now open the window on the next frame
void vjGlPipe::addWindow(vjGlWindow* win)
{
   vjGuard<vjMutex> guardNew(newWinLock);       // Protect the data
   newWins.push_back(win);
}

// The main loop routine
void vjGlPipe::controlLoop(void* nullParam)
{
   mThreadRunning = true;     // We are running

   while (!controlExit)
   {
      checkForNewWindows();      // Checks for new windows to open
      checkForWindowsToClose();  // Checks for closing windows

      // wait for render signal
      renderCond.acquire();
      {        // Wait for rendering == RENDERING
         while (renderState != RENDERING)
            renderCond.wait();
         /* Do nothing */
      }
      renderCond.release();

         // --- Call the pipe pre-draw function --- //
      vjGlApp* theApp = glManager->getApp();

         // Should I get into a context
      theApp->pipePreDraw();                    // Call pipe pre-draw function

      for (int winId=0;winId < openWins.size();winId++)
         renderWindow(openWins[winId]);

      // Done rendering. Tell people that we are waiting now.
      renderCond.acquire();
      {
         renderState = WAITING;
         renderCond.signal();
      }
      renderCond.release();
   }

   mThreadRunning = false;     // We are not running
}

/**  Checks for any new windows to add to the pipe
 * POST: Any new windows will be opened and added to the pipe's rendering list
 */
void vjGlPipe::checkForNewWindows()
{
   vjGlApp* theApp = glManager->getApp();    // Get the application

   if (newWins.size() > 0)  // If there are new windows added
   {
      vjGuard<vjMutex> guardNew(newWinLock);
      vjGuard<vjMutex> guardOpen(openWinLock);

      for (int winNum=0; winNum<newWins.size(); winNum++)
      {
         newWins[winNum]->open();
         newWins[winNum]->makeCurrent();
         theApp->contextInit();              // Call context init function
         vjDEBUG(2) << "vjGlPipe::checkForNewWindows: Just opened window:\n" << *(newWins[winNum]) << endl;
         openWins.push_back(newWins[winNum]);
      }

      newWins.erase(newWins.begin(), newWins.end());
   }
}

/**   Renders the window using OpenGL
 * POST: win is rendered (In stereo if it is a stereo window)
 */
void vjGlPipe::renderWindow(vjGlWindow* win)
{
   vjGlApp* theApp = glManager->getApp();       // Get application for easy access
   theApp->setContextId(win->getId());          // Set the context id for application

   win->makeCurrent();

   if (!win->getDisplay()->isSimulator())      // NON-SIMULATOR
   {
      win->setLeftEye();
      theApp->draw();

      if (win->isStereo())
      {
         win->setRightEye();
         theApp->draw();
      }
   }
   else                                   // SIMULATOR
   {
      win->setCameraEye();
      theApp->draw();
      glManager->drawSimulator(win->getDisplay()->mSim);
   }

   win->swapBuffers();     // Swap those buffers
}
<commit_msg>Added glFlush before swapping.<commit_after>#include <config.h>

#ifdef VJ_OS_HPUX
#   include <algorithm>
#else
#   if defined(VJ_USE_PTHREADS) && ! defined(_PTHREADS)
#       define _PTHREADS
#   endif

#   include <algo.h>
#endif

#include <Kernel/GL/vjGlPipe.h>
#include <Threads/vjThread.h>
#include <Sync/vjGuard.h>
#include <Kernel/vjDebug.h>
#include <GL/gl.h>

/** Start the pipe running
 * POST: The pipe has it's own thread of control and is ready to operate
 */
int vjGlPipe::start()
{
   vjASSERT(mThreadRunning == false);        // We should not be running yet

   // Create a new thread to handle the control loop
   vjThreadId* controlPid;

   vjThreadMemberFunctor<vjGlPipe>* memberFunctor =
   new vjThreadMemberFunctor<vjGlPipe>(this, &vjGlPipe::controlLoop, NULL);

   controlPid = vjThread::spawn(memberFunctor, 0);

   cerr << "vjGlPipe::start: Started control loop.  " << *controlPid << endl;
   return 1;
}

/** Trigger rendering of the pipe to start
 * POST: The pipe has be told to start rendering
 */
void vjGlPipe::triggerRender()
{
   vjASSERT(mThreadRunning == true);      // We must be running

   renderCond.acquire();
   {
      renderState = RENDERING;
      renderCond.signal();
   }
   renderCond.release();
}

/** Blocks until rendering of the windows is completed
 * POST: The pipe has completed its rendering
 */
void vjGlPipe::completeRender()
{
   vjASSERT(mThreadRunning == true);      // We must be running

   renderCond.acquire();
   {        // Wait for renderState == WAITING
      while (renderState != WAITING)
         renderCond.wait();
      /* Do nothing */
   }
   renderCond.release();
}

/// Add a GLWindow to the window list
// Control loop must now open the window on the next frame
void vjGlPipe::addWindow(vjGlWindow* win)
{
   vjGuard<vjMutex> guardNew(newWinLock);       // Protect the data
   newWins.push_back(win);
}

// The main loop routine
void vjGlPipe::controlLoop(void* nullParam)
{
   mThreadRunning = true;     // We are running

   while (!controlExit)
   {
      checkForNewWindows();      // Checks for new windows to open
      checkForWindowsToClose();  // Checks for closing windows

      // wait for render signal
      renderCond.acquire();
      {        // Wait for rendering == RENDERING
         while (renderState != RENDERING)
            renderCond.wait();
         /* Do nothing */
      }
      renderCond.release();

         // --- Call the pipe pre-draw function --- //
      vjGlApp* theApp = glManager->getApp();

         // Should I get into a context
      theApp->pipePreDraw();                    // Call pipe pre-draw function

      for (int winId=0;winId < openWins.size();winId++)
         renderWindow(openWins[winId]);

      // Done rendering. Tell people that we are waiting now.
      renderCond.acquire();
      {
         renderState = WAITING;
         renderCond.signal();
      }
      renderCond.release();
   }

   mThreadRunning = false;     // We are not running
}

/**  Checks for any new windows to add to the pipe
 * POST: Any new windows will be opened and added to the pipe's rendering list
 */
void vjGlPipe::checkForNewWindows()
{
   vjGlApp* theApp = glManager->getApp();    // Get the application

   if (newWins.size() > 0)  // If there are new windows added
   {
      vjGuard<vjMutex> guardNew(newWinLock);
      vjGuard<vjMutex> guardOpen(openWinLock);

      for (int winNum=0; winNum<newWins.size(); winNum++)
      {
         newWins[winNum]->open();
         newWins[winNum]->makeCurrent();
         theApp->contextInit();              // Call context init function
         vjDEBUG(2) << "vjGlPipe::checkForNewWindows: Just opened window:\n" << *(newWins[winNum]) << endl;
         openWins.push_back(newWins[winNum]);
      }

      newWins.erase(newWins.begin(), newWins.end());
   }
}

/**   Renders the window using OpenGL
 * POST: win is rendered (In stereo if it is a stereo window)
 */
void vjGlPipe::renderWindow(vjGlWindow* win)
{
   vjGlApp* theApp = glManager->getApp();       // Get application for easy access
   theApp->setContextId(win->getId());          // Set the context id for application

   win->makeCurrent();

   if (!win->getDisplay()->isSimulator())      // NON-SIMULATOR
   {
      win->setLeftEye();
      theApp->draw();

      if (win->isStereo())
      {
         win->setRightEye();
         theApp->draw();
      }
   }
   else                                   // SIMULATOR
   {
      win->setCameraEye();
      theApp->draw();
      glManager->drawSimulator(win->getDisplay()->mSim);
   }

   glFlush();              // Flush the OpenGL commands
   win->swapBuffers();     // Swap those buffers
}
<|endoftext|>


<commit_before>~/*
 Copyright (C) 2011 by Ivan Safrin

 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 "PolySound.h"
#include <vorbis/vorbisfile.h>
#include "PolyString.h"
#include "PolyLogger.h"

#include "OSBasics.h"
#include <string>
#include <vector>

using namespace std;
using namespace Polycode;

size_t custom_readfunc(void *ptr, size_t size, size_t nmemb, void *datasource) {
	OSFILE *file = (OSFILE*) datasource;
	return OSBasics::read(ptr, size, nmemb, file);
}

int custom_seekfunc(void *datasource, ogg_int64_t offset, int whence){
	OSFILE *file = (OSFILE*) datasource;
	return OSBasics::seek(file, offset, whence);
}

int custom_closefunc(void *datasource) {
	OSFILE *file = (OSFILE*) datasource;
	return OSBasics::close(file);
}

long custom_tellfunc(void *datasource) {
	OSFILE *file = (OSFILE*) datasource;
	return OSBasics::tell(file);
}

Sound::Sound(const String& fileName) {
	String extension;
	size_t found;
	found=fileName.rfind(".");
	if (found!=string::npos) {
		extension = fileName.substr(found+1);
	} else {
		extension = "";
	}

	ALuint buffer;
	if(extension == "wav" || extension == "WAV") {
		buffer = loadWAV(fileName);
	} else if(extension == "ogg" || extension == "OGG") {
		buffer = loadOGG(fileName);
	}

	soundSource = GenSource(buffer);
	setIsPositional(false);
}

Sound::~Sound() {
	Logger::log("destroying sound...\n");
	alDeleteSources(1,&soundSource);
}

void Sound::soundCheck(bool result, const String& err) {
	if(!result)
		soundError(err);
}

void Sound::soundError(const String& err) {
	Logger::log("SOUND ERROR: %s\n", err.c_str());
}

unsigned long Sound::readByte32(const unsigned char buffer[4]) {
#if TAU_BIG_ENDIAN
    return (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3];
#else
    return (buffer[3] << 24) + (buffer[2] << 16) + (buffer[1] << 8) + buffer[0];
#endif
}

unsigned short Sound::readByte16(const unsigned char buffer[2]) {
#if TAU_BIG_ENDIAN
    return (buffer[0] << 8) + buffer[1];
#else
    return (buffer[1] << 8) + buffer[0];
#endif
}

void Sound::Play(bool loop) {
	if(!loop) {
		alSourcei(soundSource, AL_LOOPING, AL_FALSE);
	} else {
		alSourcei(soundSource, AL_LOOPING, AL_TRUE);
	}
	alSourcePlay(soundSource);
}

bool Sound::isPlaying() {
	ALenum state;
	alGetSourcei(soundSource, AL_SOURCE_STATE, &state);
	return (state == AL_PLAYING);
}

void Sound::setVolume(Number newVolume) {
	alSourcef(soundSource, AL_GAIN, newVolume);
}

void Sound::setPitch(Number newPitch) {
	alSourcef(soundSource, AL_PITCH, newPitch);
}

void Sound::setSoundPosition(Vector3 position) {
	if(isPositional)
		alSource3f(soundSource,AL_POSITION, position.x, position.y, position.z);
}

void Sound::setSoundVelocity(Vector3 velocity) {
	if(isPositional)
		alSource3f(soundSource,AL_VELOCITY, velocity.x, velocity.y, velocity.z);
}

void Sound::setSoundDirection(Vector3 direction) {
	if(isPositional)
		alSource3f(soundSource,AL_DIRECTION, direction.x, direction.y, direction.z);
}

void Sound::setPositionalProperties(Number referenceDistance, Number maxDistance) {
	alSourcef(soundSource,AL_REFERENCE_DISTANCE, referenceDistance);
	alSourcef(soundSource,AL_MAX_DISTANCE, maxDistance);
}

void Sound::setIsPositional(bool isPositional) {
	this->isPositional = isPositional;
	if(isPositional) {
		alSourcei(soundSource, AL_SOURCE_RELATIVE, AL_FALSE);
	} else {
		alSourcei(soundSource, AL_SOURCE_RELATIVE, AL_TRUE);
		alSource3f(soundSource,AL_POSITION, 0,0,0);
		alSource3f(soundSource,AL_VELOCITY, 0,0,0);
		alSource3f(soundSource,AL_DIRECTION, 0,0,0);
	}
}

void Sound::checkALError(const String& operation) {
	ALenum error = alGetError();
	if(error != AL_NO_ERROR) {
		switch(error) {
			case AL_NO_ERROR:
				soundError(operation + ": " +ALNoErrorStr);
				break;
			case AL_INVALID_NAME:
				soundError(operation +": " + ALInvalidNameStr);
				break;
			case AL_INVALID_ENUM:
				soundError(operation + ": " +ALInvalidEnumStr);
				break;
			case AL_INVALID_VALUE:
				soundError(operation + ": " +ALInvalidValueStr);
				break;
			case AL_INVALID_OPERATION:
				soundError(operation + ": " +ALInvalidOpStr);
				break;
			case AL_OUT_OF_MEMORY:
				soundError(operation + ": " +ALOutOfMemoryStr);
				break;
			default:
				soundError(operation + ": " +ALOtherErrorStr);
				break;
		}
	}
}

void Sound::Stop() {
	alSourceStop(soundSource);
}

ALuint Sound::GenSource() {
	ALuint source;
	bool looping = false;
	ALfloat sourcePos[] = {0.0, 0.0, 0.0};
	ALfloat sourceVel[] = {0.0, 0.0, 0.0};

	alGetError();

	alGenSources(1, &source);
	checkALError("Generating sources");

	alSourcef(source, AL_PITCH, 1.0);
	alSourcef(source, AL_GAIN, 1.0);
	alSourcefv(source, AL_POSITION, sourcePos);
	alSourcefv(source, AL_VELOCITY, sourceVel);
	alSourcei(source, AL_LOOPING, looping);

	checkALError("Setting source properties");

	return source;
}

ALuint Sound::GenSource(ALuint buffer) {
	alGetError();
	ALuint source = GenSource();
	alSourcei(source, AL_BUFFER, buffer);
	checkALError("Setting source buffer");
	return source;
}

ALuint Sound::loadOGG(const String& fileName) {

	vector<char> buffer;

	ALuint bufferID = AL_NONE;
	alGenBuffers(1, &bufferID);
	int endian = 0;             // 0 for Little-Endian, 1 for Big-Endian
	int bitStream;
	long bytes;
	char array[BUFFER_SIZE];    // Local fixed size array
	OSFILE *f;
	ALenum format;
	ALsizei freq;

	// Open for binary reading
	f = OSBasics::open(fileName.c_str(), "rb");
	if(!f) {
		soundError("Error loading OGG file!\n");
		return bufferID;
	}
	vorbis_info *pInfo;
	OggVorbis_File oggFile;

	ov_callbacks callbacks;
	callbacks.read_func = custom_readfunc;
	callbacks.seek_func = custom_seekfunc;
	callbacks.close_func = custom_closefunc;
	callbacks.tell_func = custom_tellfunc;

	ov_open_callbacks( (void*)f, &oggFile, NULL, 0, callbacks);
//	ov_open(f, &oggFile, NULL, 0);
	// Get some information about the OGG file
	pInfo = ov_info(&oggFile, -1);

	// Check the number of channels... always use 16-bit samples
	if (pInfo->channels == 1)
		format = AL_FORMAT_MONO16;
	else
		format = AL_FORMAT_STEREO16;
	// end if

	// The frequency of the sampling rate
	freq = pInfo->rate;
	do {
		// Read up to a buffer's worth of decoded sound data
		bytes = ov_read(&oggFile, array, BUFFER_SIZE, endian, 2, 1, &bitStream);
		// Append to end of buffer
		buffer.insert(buffer.end(), array, array + bytes);
	} while (bytes > 0);
	ov_clear(&oggFile);

	alBufferData(bufferID, format, &buffer[0], static_cast<ALsizei>(buffer.size()), freq);

	OSBasics::close(f);
	f = NULL;

	return bufferID;
}

ALuint Sound::loadWAV(const String& fileName) {
	long bytes;
	vector <char> data;
	ALenum format;
	ALsizei freq;

	// Local resources
	OSFILE *f = NULL;
	char *array = NULL;
	ALuint buffer = AL_NONE;

	alGetError();

		// Open for binary reading
		f = OSBasics::open(fileName.c_str(), "rb");
		if (!f)
			soundError("LoadWav: Could not load wav from " + fileName);

		// buffers
		char magic[5];
		magic[4] = '\0';
		unsigned char buffer32[4];
		unsigned char buffer16[2];

		// check magic
		soundCheck(OSBasics::read(magic,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		soundCheck(String(magic) == "RIFF", "LoadWav: Wrong wav file format. This file is not a .wav file (no RIFF magic): "+ fileName );

		// skip 4 bytes (file size)
		OSBasics::seek(f,4,SEEK_CUR);

		// check file format
		soundCheck(OSBasics::read(magic,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		soundCheck(String(magic) == "WAVE", "LoadWav: Wrong wav file format. This file is not a .wav file (no WAVE format): "+ fileName );

		// check 'fmt ' sub chunk (1)
		soundCheck(OSBasics::read(magic,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		soundCheck(String(magic) == "fmt ", "LoadWav: Wrong wav file format. This file is not a .wav file (no 'fmt ' subchunk): "+ fileName );

		// read (1)'s size
		soundCheck(OSBasics::read(buffer32,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned long subChunk1Size = readByte32(buffer32);
		soundCheck(subChunk1Size >= 16, "Wrong wav file format. This file is not a .wav file ('fmt ' chunk too small, truncated file?): "+ fileName );

		// check PCM audio format
		soundCheck(OSBasics::read(buffer16,2,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned short audioFormat = readByte16(buffer16);
		soundCheck(audioFormat == 1, "LoadWav: Wrong wav file format. This file is not a .wav file (audio format is not PCM): "+ fileName );

		// read number of channels
		soundCheck(OSBasics::read(buffer16,2,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned short channels = readByte16(buffer16);

		// read frequency (sample rate)
		soundCheck(OSBasics::read(buffer32,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned long frequency = readByte32(buffer32);

		// skip 6 bytes (Byte rate (4), Block align (2))
		OSBasics::seek(f,6,SEEK_CUR);

		// read bits per sample
		soundCheck(OSBasics::read(buffer16,2,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned short bps = readByte16(buffer16);

		if (channels == 1)
			format = (bps == 8) ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16;
		else
			format = (bps == 8) ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16;

		// check 'data' sub chunk (2)
		soundCheck(OSBasics::read(magic,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		soundCheck(String(magic) == "data", "LoadWav: Wrong wav file format. This file is not a .wav file (no data subchunk): "+ fileName );

		soundCheck(OSBasics::read(buffer32,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned long subChunk2Size = readByte32(buffer32);

		// The frequency of the sampling rate
		freq = frequency;
		soundCheck(sizeof(freq) == sizeof(frequency), "LoadWav: freq and frequency different sizes");

		array = new char[BUFFER_SIZE];

		while (data.size() != subChunk2Size) {
			// Read up to a buffer's worth of decoded sound data
			bytes = OSBasics::read(array, 1, BUFFER_SIZE, f);

			if (bytes <= 0)
				break;

			if (data.size() + bytes > subChunk2Size)
				bytes = subChunk2Size - data.size();

			// Append to end of buffer
			data.insert(data.end(), array, array + bytes);
		};

		delete []array;
		array = NULL;

		OSBasics::close(f);
		f = NULL;

		alGenBuffers(1, &buffer);
		soundCheck(alGetError() == AL_NO_ERROR, "LoadWav: Could not generate buffer");
		soundCheck(AL_NONE != buffer, "LoadWav: Could not generate buffer");

		alBufferData(buffer, format, &data[0], data.size(), freq);
		soundCheck(alGetError() == AL_NO_ERROR, "LoadWav: Could not load buffer data");

		return buffer;
//		if (buffer)
//			if (alIsBuffer(buffer) == AL_TRUE)
//				alDeleteBuffers(1, &buffer);
//
//		if (array)
//			delete []array;
//
//		if (f)
//			OSBasics::close(f);
//
//		throw (e);

}
<commit_msg>Stray character in checkin<commit_after>/*
 Copyright (C) 2011 by Ivan Safrin

 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 "PolySound.h"
#include <vorbis/vorbisfile.h>
#include "PolyString.h"
#include "PolyLogger.h"

#include "OSBasics.h"
#include <string>
#include <vector>

using namespace std;
using namespace Polycode;

size_t custom_readfunc(void *ptr, size_t size, size_t nmemb, void *datasource) {
	OSFILE *file = (OSFILE*) datasource;
	return OSBasics::read(ptr, size, nmemb, file);
}

int custom_seekfunc(void *datasource, ogg_int64_t offset, int whence){
	OSFILE *file = (OSFILE*) datasource;
	return OSBasics::seek(file, offset, whence);
}

int custom_closefunc(void *datasource) {
	OSFILE *file = (OSFILE*) datasource;
	return OSBasics::close(file);
}

long custom_tellfunc(void *datasource) {
	OSFILE *file = (OSFILE*) datasource;
	return OSBasics::tell(file);
}

Sound::Sound(const String& fileName) {
	String extension;
	size_t found;
	found=fileName.rfind(".");
	if (found!=string::npos) {
		extension = fileName.substr(found+1);
	} else {
		extension = "";
	}

	ALuint buffer;
	if(extension == "wav" || extension == "WAV") {
		buffer = loadWAV(fileName);
	} else if(extension == "ogg" || extension == "OGG") {
		buffer = loadOGG(fileName);
	}

	soundSource = GenSource(buffer);
	setIsPositional(false);
}

Sound::~Sound() {
	Logger::log("destroying sound...\n");
	alDeleteSources(1,&soundSource);
}

void Sound::soundCheck(bool result, const String& err) {
	if(!result)
		soundError(err);
}

void Sound::soundError(const String& err) {
	Logger::log("SOUND ERROR: %s\n", err.c_str());
}

unsigned long Sound::readByte32(const unsigned char buffer[4]) {
#if TAU_BIG_ENDIAN
    return (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3];
#else
    return (buffer[3] << 24) + (buffer[2] << 16) + (buffer[1] << 8) + buffer[0];
#endif
}

unsigned short Sound::readByte16(const unsigned char buffer[2]) {
#if TAU_BIG_ENDIAN
    return (buffer[0] << 8) + buffer[1];
#else
    return (buffer[1] << 8) + buffer[0];
#endif
}

void Sound::Play(bool loop) {
	if(!loop) {
		alSourcei(soundSource, AL_LOOPING, AL_FALSE);
	} else {
		alSourcei(soundSource, AL_LOOPING, AL_TRUE);
	}
	alSourcePlay(soundSource);
}

bool Sound::isPlaying() {
	ALenum state;
	alGetSourcei(soundSource, AL_SOURCE_STATE, &state);
	return (state == AL_PLAYING);
}

void Sound::setVolume(Number newVolume) {
	alSourcef(soundSource, AL_GAIN, newVolume);
}

void Sound::setPitch(Number newPitch) {
	alSourcef(soundSource, AL_PITCH, newPitch);
}

void Sound::setSoundPosition(Vector3 position) {
	if(isPositional)
		alSource3f(soundSource,AL_POSITION, position.x, position.y, position.z);
}

void Sound::setSoundVelocity(Vector3 velocity) {
	if(isPositional)
		alSource3f(soundSource,AL_VELOCITY, velocity.x, velocity.y, velocity.z);
}

void Sound::setSoundDirection(Vector3 direction) {
	if(isPositional)
		alSource3f(soundSource,AL_DIRECTION, direction.x, direction.y, direction.z);
}

void Sound::setPositionalProperties(Number referenceDistance, Number maxDistance) {
	alSourcef(soundSource,AL_REFERENCE_DISTANCE, referenceDistance);
	alSourcef(soundSource,AL_MAX_DISTANCE, maxDistance);
}

void Sound::setIsPositional(bool isPositional) {
	this->isPositional = isPositional;
	if(isPositional) {
		alSourcei(soundSource, AL_SOURCE_RELATIVE, AL_FALSE);
	} else {
		alSourcei(soundSource, AL_SOURCE_RELATIVE, AL_TRUE);
		alSource3f(soundSource,AL_POSITION, 0,0,0);
		alSource3f(soundSource,AL_VELOCITY, 0,0,0);
		alSource3f(soundSource,AL_DIRECTION, 0,0,0);
	}
}

void Sound::checkALError(const String& operation) {
	ALenum error = alGetError();
	if(error != AL_NO_ERROR) {
		switch(error) {
			case AL_NO_ERROR:
				soundError(operation + ": " +ALNoErrorStr);
				break;
			case AL_INVALID_NAME:
				soundError(operation +": " + ALInvalidNameStr);
				break;
			case AL_INVALID_ENUM:
				soundError(operation + ": " +ALInvalidEnumStr);
				break;
			case AL_INVALID_VALUE:
				soundError(operation + ": " +ALInvalidValueStr);
				break;
			case AL_INVALID_OPERATION:
				soundError(operation + ": " +ALInvalidOpStr);
				break;
			case AL_OUT_OF_MEMORY:
				soundError(operation + ": " +ALOutOfMemoryStr);
				break;
			default:
				soundError(operation + ": " +ALOtherErrorStr);
				break;
		}
	}
}

void Sound::Stop() {
	alSourceStop(soundSource);
}

ALuint Sound::GenSource() {
	ALuint source;
	bool looping = false;
	ALfloat sourcePos[] = {0.0, 0.0, 0.0};
	ALfloat sourceVel[] = {0.0, 0.0, 0.0};

	alGetError();

	alGenSources(1, &source);
	checkALError("Generating sources");

	alSourcef(source, AL_PITCH, 1.0);
	alSourcef(source, AL_GAIN, 1.0);
	alSourcefv(source, AL_POSITION, sourcePos);
	alSourcefv(source, AL_VELOCITY, sourceVel);
	alSourcei(source, AL_LOOPING, looping);

	checkALError("Setting source properties");

	return source;
}

ALuint Sound::GenSource(ALuint buffer) {
	alGetError();
	ALuint source = GenSource();
	alSourcei(source, AL_BUFFER, buffer);
	checkALError("Setting source buffer");
	return source;
}

ALuint Sound::loadOGG(const String& fileName) {

	vector<char> buffer;

	ALuint bufferID = AL_NONE;
	alGenBuffers(1, &bufferID);
	int endian = 0;             // 0 for Little-Endian, 1 for Big-Endian
	int bitStream;
	long bytes;
	char array[BUFFER_SIZE];    // Local fixed size array
	OSFILE *f;
	ALenum format;
	ALsizei freq;

	// Open for binary reading
	f = OSBasics::open(fileName.c_str(), "rb");
	if(!f) {
		soundError("Error loading OGG file!\n");
		return bufferID;
	}
	vorbis_info *pInfo;
	OggVorbis_File oggFile;

	ov_callbacks callbacks;
	callbacks.read_func = custom_readfunc;
	callbacks.seek_func = custom_seekfunc;
	callbacks.close_func = custom_closefunc;
	callbacks.tell_func = custom_tellfunc;

	ov_open_callbacks( (void*)f, &oggFile, NULL, 0, callbacks);
//	ov_open(f, &oggFile, NULL, 0);
	// Get some information about the OGG file
	pInfo = ov_info(&oggFile, -1);

	// Check the number of channels... always use 16-bit samples
	if (pInfo->channels == 1)
		format = AL_FORMAT_MONO16;
	else
		format = AL_FORMAT_STEREO16;
	// end if

	// The frequency of the sampling rate
	freq = pInfo->rate;
	do {
		// Read up to a buffer's worth of decoded sound data
		bytes = ov_read(&oggFile, array, BUFFER_SIZE, endian, 2, 1, &bitStream);
		// Append to end of buffer
		buffer.insert(buffer.end(), array, array + bytes);
	} while (bytes > 0);
	ov_clear(&oggFile);

	alBufferData(bufferID, format, &buffer[0], static_cast<ALsizei>(buffer.size()), freq);

	OSBasics::close(f);
	f = NULL;

	return bufferID;
}

ALuint Sound::loadWAV(const String& fileName) {
	long bytes;
	vector <char> data;
	ALenum format;
	ALsizei freq;

	// Local resources
	OSFILE *f = NULL;
	char *array = NULL;
	ALuint buffer = AL_NONE;

	alGetError();

		// Open for binary reading
		f = OSBasics::open(fileName.c_str(), "rb");
		if (!f)
			soundError("LoadWav: Could not load wav from " + fileName);

		// buffers
		char magic[5];
		magic[4] = '\0';
		unsigned char buffer32[4];
		unsigned char buffer16[2];

		// check magic
		soundCheck(OSBasics::read(magic,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		soundCheck(String(magic) == "RIFF", "LoadWav: Wrong wav file format. This file is not a .wav file (no RIFF magic): "+ fileName );

		// skip 4 bytes (file size)
		OSBasics::seek(f,4,SEEK_CUR);

		// check file format
		soundCheck(OSBasics::read(magic,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		soundCheck(String(magic) == "WAVE", "LoadWav: Wrong wav file format. This file is not a .wav file (no WAVE format): "+ fileName );

		// check 'fmt ' sub chunk (1)
		soundCheck(OSBasics::read(magic,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		soundCheck(String(magic) == "fmt ", "LoadWav: Wrong wav file format. This file is not a .wav file (no 'fmt ' subchunk): "+ fileName );

		// read (1)'s size
		soundCheck(OSBasics::read(buffer32,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned long subChunk1Size = readByte32(buffer32);
		soundCheck(subChunk1Size >= 16, "Wrong wav file format. This file is not a .wav file ('fmt ' chunk too small, truncated file?): "+ fileName );

		// check PCM audio format
		soundCheck(OSBasics::read(buffer16,2,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned short audioFormat = readByte16(buffer16);
		soundCheck(audioFormat == 1, "LoadWav: Wrong wav file format. This file is not a .wav file (audio format is not PCM): "+ fileName );

		// read number of channels
		soundCheck(OSBasics::read(buffer16,2,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned short channels = readByte16(buffer16);

		// read frequency (sample rate)
		soundCheck(OSBasics::read(buffer32,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned long frequency = readByte32(buffer32);

		// skip 6 bytes (Byte rate (4), Block align (2))
		OSBasics::seek(f,6,SEEK_CUR);

		// read bits per sample
		soundCheck(OSBasics::read(buffer16,2,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned short bps = readByte16(buffer16);

		if (channels == 1)
			format = (bps == 8) ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16;
		else
			format = (bps == 8) ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16;

		// check 'data' sub chunk (2)
		soundCheck(OSBasics::read(magic,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		soundCheck(String(magic) == "data", "LoadWav: Wrong wav file format. This file is not a .wav file (no data subchunk): "+ fileName );

		soundCheck(OSBasics::read(buffer32,4,1,f) == 1, "LoadWav: Cannot read wav file "+ fileName );
		unsigned long subChunk2Size = readByte32(buffer32);

		// The frequency of the sampling rate
		freq = frequency;
		soundCheck(sizeof(freq) == sizeof(frequency), "LoadWav: freq and frequency different sizes");

		array = new char[BUFFER_SIZE];

		while (data.size() != subChunk2Size) {
			// Read up to a buffer's worth of decoded sound data
			bytes = OSBasics::read(array, 1, BUFFER_SIZE, f);

			if (bytes <= 0)
				break;

			if (data.size() + bytes > subChunk2Size)
				bytes = subChunk2Size - data.size();

			// Append to end of buffer
			data.insert(data.end(), array, array + bytes);
		};

		delete []array;
		array = NULL;

		OSBasics::close(f);
		f = NULL;

		alGenBuffers(1, &buffer);
		soundCheck(alGetError() == AL_NO_ERROR, "LoadWav: Could not generate buffer");
		soundCheck(AL_NONE != buffer, "LoadWav: Could not generate buffer");

		alBufferData(buffer, format, &data[0], data.size(), freq);
		soundCheck(alGetError() == AL_NO_ERROR, "LoadWav: Could not load buffer data");

		return buffer;
//		if (buffer)
//			if (alIsBuffer(buffer) == AL_TRUE)
//				alDeleteBuffers(1, &buffer);
//
//		if (array)
//			delete []array;
//
//		if (f)
//			OSBasics::close(f);
//
//		throw (e);

}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgParticle/ParticleEffect>
#include <osgParticle/ParticleSystemUpdater>
#include <osg/Geode>

using namespace osgParticle;

ParticleEffect::ParticleEffect(const ParticleEffect& copy, const osg::CopyOp& copyop):
    osg::Group(copy,copyop),/*,
    _particleSystem(copy._particleSystem.valid()?copy._particleSystem->clone():0)*/
    _useLocalParticleSystem(copy._useLocalParticleSystem),
    _defaultParticleTemplate(copy._defaultParticleTemplate),
    _position(copy._position),
    _scale(copy._scale),
    _intensity(copy._intensity),
    _startTime(copy._startTime),
    _emitterDuration(copy._emitterDuration),
    _wind(copy._wind)
{
}

void ParticleEffect::setUseLocalParticleSystem(bool local)
{
    if (_useLocalParticleSystem==local) return;

    _useLocalParticleSystem = local;
    buildEffect();
}

void ParticleEffect::setDefaultParticleTemplate(const Particle& p)
{
    _defaultParticleTemplate = p;
    setUpEmitterAndProgram();
}

void ParticleEffect::setPosition(const osg::Vec3& position)
{
    if (_position==position) return;

    _position = position;
    setUpEmitterAndProgram();
}

void ParticleEffect::setScale(float scale)
{
    if (_scale==scale) return;

    _scale = scale;
    setUpEmitterAndProgram();
}

void ParticleEffect::setIntensity(float intensity)
{
    if (_intensity==intensity) return;

    _intensity = intensity;
    setUpEmitterAndProgram();
}

void ParticleEffect::setStartTime(double startTime)
{
    if (_startTime==startTime) return;

    _startTime =startTime;
    setUpEmitterAndProgram();
}

void ParticleEffect::setEmitterDuration(double duration)
{
    if (_emitterDuration==duration) return;

    _emitterDuration = duration;
    setUpEmitterAndProgram();
}

void ParticleEffect::setParticleDuration(double duration)
{
    if (_defaultParticleTemplate.getLifeTime()==duration) return;

    _defaultParticleTemplate.setLifeTime(duration);

    setUpEmitterAndProgram();
}

void ParticleEffect::setWind(const osg::Vec3& wind)
{
    if (_wind==wind) return;

    _wind = wind;
    setUpEmitterAndProgram();
}

void ParticleEffect::setParticleSystem(ParticleSystem* ps)
{
    if (_particleSystem==ps) return;

    _particleSystem = ps;
    buildEffect();
}

void ParticleEffect::setDefaults()
{
    _useLocalParticleSystem = true;
    _scale = 1.0f;
    _intensity = 1.0f;
    _startTime = 0.0;
    _emitterDuration = 1.0;
    _wind.set(0.0f,0.0f,0.0f);
}

void ParticleEffect::buildEffect()
{
    setUpEmitterAndProgram();

    Emitter* emitter = getEmitter();
    Program* program = getProgram();
    ParticleSystem* particleSystem = getParticleSystem();

    if (!emitter || !particleSystem || !program) return;

    // clear the children.
    removeChild(0,getNumChildren());

    // add the emitter
    addChild(emitter);

    // add the program to update the particles
    addChild(program);

    // add the particle system updater.
    osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater;
    psu->addParticleSystem(particleSystem);
    addChild(psu);

    if (_useLocalParticleSystem)
    {
        // add the geode to the scene graph
        osg::Geode *geode = new osg::Geode;
        geode->addDrawable(particleSystem);
        addChild(geode);
    }
}

<commit_msg>Added setTextureFileName method.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgParticle/ParticleEffect>
#include <osgParticle/ParticleSystemUpdater>
#include <osg/Geode>

using namespace osgParticle;

ParticleEffect::ParticleEffect(const ParticleEffect& copy, const osg::CopyOp& copyop):
    osg::Group(copy,copyop),/*,
    _particleSystem(copy._particleSystem.valid()?copy._particleSystem->clone():0)*/
    _useLocalParticleSystem(copy._useLocalParticleSystem),
    _defaultParticleTemplate(copy._defaultParticleTemplate),
    _position(copy._position),
    _scale(copy._scale),
    _intensity(copy._intensity),
    _startTime(copy._startTime),
    _emitterDuration(copy._emitterDuration),
    _wind(copy._wind)
{
}

void ParticleEffect::setUseLocalParticleSystem(bool local)
{
    if (_useLocalParticleSystem==local) return;

    _useLocalParticleSystem = local;
    buildEffect();
}

void ParticleEffect::setTextureFileName(const std::string& filename)
{
    _textureFileName = filename;
    setUpEmitterAndProgram();
}

void ParticleEffect::setDefaultParticleTemplate(const Particle& p)
{
    _defaultParticleTemplate = p;
    setUpEmitterAndProgram();
}

void ParticleEffect::setPosition(const osg::Vec3& position)
{
    if (_position==position) return;

    _position = position;
    setUpEmitterAndProgram();
}

void ParticleEffect::setScale(float scale)
{
    if (_scale==scale) return;

    _scale = scale;
    setUpEmitterAndProgram();
}

void ParticleEffect::setIntensity(float intensity)
{
    if (_intensity==intensity) return;

    _intensity = intensity;
    setUpEmitterAndProgram();
}

void ParticleEffect::setStartTime(double startTime)
{
    if (_startTime==startTime) return;

    _startTime =startTime;
    setUpEmitterAndProgram();
}

void ParticleEffect::setEmitterDuration(double duration)
{
    if (_emitterDuration==duration) return;

    _emitterDuration = duration;
    setUpEmitterAndProgram();
}

void ParticleEffect::setParticleDuration(double duration)
{
    if (_defaultParticleTemplate.getLifeTime()==duration) return;

    _defaultParticleTemplate.setLifeTime(duration);

    setUpEmitterAndProgram();
}

void ParticleEffect::setWind(const osg::Vec3& wind)
{
    if (_wind==wind) return;

    _wind = wind;
    setUpEmitterAndProgram();
}

void ParticleEffect::setParticleSystem(ParticleSystem* ps)
{
    if (_particleSystem==ps) return;

    _particleSystem = ps;
    buildEffect();
}

void ParticleEffect::setDefaults()
{
    _useLocalParticleSystem = true;
    _scale = 1.0f;
    _intensity = 1.0f;
    _startTime = 0.0;
    _emitterDuration = 1.0;
    _wind.set(0.0f,0.0f,0.0f);
}

void ParticleEffect::buildEffect()
{
    setUpEmitterAndProgram();

    Emitter* emitter = getEmitter();
    Program* program = getProgram();
    ParticleSystem* particleSystem = getParticleSystem();

    if (!emitter || !particleSystem || !program) return;

    // clear the children.
    removeChild(0,getNumChildren());

    // add the emitter
    addChild(emitter);

    // add the program to update the particles
    addChild(program);

    // add the particle system updater.
    osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater;
    psu->addParticleSystem(particleSystem);
    addChild(psu);

    if (_useLocalParticleSystem)
    {
        // add the geode to the scene graph
        osg::Geode *geode = new osg::Geode;
        geode->addDrawable(particleSystem);
        addChild(geode);
    }
}

<|endoftext|>