<commit_before>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
#include <bse/testing.hh>
#include <bse/bse.hh>
#include <bse/bsemain.hh> // FIXME: bse_init_test
#include "ipc.hh"

#define DEBUG(...)              do { break; Bse::printerr (__VA_ARGS__); } while (0)

static int                      jobserver (const char *const argv0, Bse::StringVector &tests);
static void BSE_NORETURN        jobclient (int jobfd);

static void
print_int_ring (SfiRing *ring)
{
  SfiRing *node;
  TNOTE ("{");
  for (node = ring; node; node = sfi_ring_walk (node, ring))
    TNOTE ("%c", char (size_t (node->data)));
  TNOTE ("}");
}

static gint
ints_cmp (gconstpointer d1,
	  gconstpointer d2,
          gpointer      data)
{
  size_t i1 = size_t (d1);
  size_t i2 = size_t (d2);
  return i1 < i2 ? -1 : i1 > i2;
}

static void
test_sfi_ring (void)
{
  gint data_array[][64] = {
    { 0, },
    { 1, 'a', },
    { 2, 'a', 'a', },
    { 2, 'a', 'b', },
    { 2, 'z', 'a', },
    { 3, 'a', 'c', 'z' },
    { 3, 'a', 'z', 'c' },
    { 3, 'c', 'a', 'z' },
    { 3, 'z', 'c', 'a' },
    { 3, 'a', 'a', 'a' },
    { 3, 'a', 'a', 'z' },
    { 3, 'a', 'z', 'a' },
    { 3, 'z', 'a', 'a' },
    { 10, 'g', 's', 't', 'y', 'x', 'q', 'i', 'n', 'j', 'a' },
    { 15, 'w', 'k', 't', 'o', 'c', 's', 'j', 'd', 'd', 'q', 'p', 'v', 'q', 'r', 'a' },
    { 26, 'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm'
      ,   'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a', },
  };

  for (uint n = 0; n < G_N_ELEMENTS (data_array); n++)
    {
      uint l = data_array[n][0];
      SfiRing *ring = NULL;
      for (uint i = 1; i <= l; i++)
	ring = sfi_ring_append (ring, (void*) size_t (data_array[n][i]));
      TNOTE ("source: ");
      print_int_ring (ring);
      ring = sfi_ring_sort (ring, ints_cmp, NULL);
      TNOTE (" sorted: ");
      print_int_ring (ring);
      TNOTE ("\n");
      sfi_ring_free (ring);
    }
}
TEST_ADD (test_sfi_ring);

static Bse::ServerS bse_server;

static void
bench_aida()
{
  using namespace Bse;
  double calls = 0, slowest = 0, fastest = 9e+9;
  for (uint j = 0; j < 37; j++)
    {
      bse_server.test_counter_set (0);
      const int count = 2999;
      const uint64_t ts0 = timestamp_benchmark();
      for (int i = 0; i < count; i++)
        bse_server.test_counter_inc_fetch ();
      const uint64 ts1 = timestamp_benchmark();
      TASSERT (bse_server.test_counter_get() == count);
      double t0 = ts0 / 1000000000.;
      double t1 = ts1 / 1000000000.;
      double call1 = (t1 - t0) / count;
      slowest = MAX (slowest, call1 * 1000000.);
      fastest = MIN (fastest, call1 * 1000000.);
      double this_calls = 1 / call1;
      calls = MAX (calls, this_calls);
    }
  double err = (slowest - fastest) / slowest;
  printout ("  BENCH    Aida: %g calls/s; fastest: %.2fus; slowest: %.2fus; err: %.2f%%\n",
            calls, fastest, slowest, err * 100);
}

int
main (int   argc,
      char *argv[])
{
  const Bse::StringVector args = Bse::cstrings_to_vector ("stand-alone=1", "wave-chunk-padding=1", NULL);
  // "wave-chunk-big-pad=2", "dcache-block-size=16"

  Bse::StringVector test_names;
  Bse::Test::TestEntries test_entries;
  int64 jobs = 0;
  int jobfd = -1;
  int64 testflags = 0;

  for (ssize_t i = 1; i < argc; i++)
    if (argv[i])
      {
        if (std::string ("--aida-bench") == argv[i])
          {
            Bse::init_async (&argc, argv, argv[0], args);
            bse_server = Bse::init_server_instance();
            bench_aida();
            return 0;
          }
        else if (std::string ("--broken") == argv[i])
          {
            testflags |= Bse::Test::BROKEN;
          }
        else if (std::string ("--slow") == argv[i])
          {
            testflags |= Bse::Test::SLOW;
          }
        else if (std::string ("--bench") == argv[i])
          {
            testflags |= Bse::Test::BENCH;
          }
        else if (std::string ("--jobfd") == argv[i] && i + 1 < argc)
          {
            jobfd = Bse::string_to_int (argv[++i]);
          }
        else if (std::string ("-j") == argv[i])
          {
            jobs = 1;
          }
        else if ('-' == argv[i][0])
          {
            Bse::printerr ("%s: unknown option: %s\n", argv[0], argv[i]);
            return 7;
          }
        else
          {
            test_names.push_back (argv[i]);
            test_entries.push_back (Bse::Test::TestEntry (argv[i]));
          }
      }

  bse_init_test (&argc, argv, args);

  if (jobfd != -1)
    jobclient (jobfd);  // noreturn

  if (test_entries.size() == 0)
    test_entries = Bse::Test::list_tests();

  if (jobs)
    {
      Bse::StringVector tests;
      for (const Bse::Test::TestEntry &entry : test_entries)
        if (0 == (entry.flags & ~testflags))
          tests.push_back (entry.ident);
      const int serverstatus = jobserver (argv[0], tests);
      exit (serverstatus);
    }

  for (Bse::Test::TestEntry entry : test_entries)
    if (0 == (entry.flags & ~testflags))
      {
        const int result = Bse::Test::run_test (entry.ident);
        if (result < 0)
          {
            Bse::printout ("  RUN…     %s\n", entry.ident);
            Bse::printout ("  FAIL     %s - test missing\n", entry.ident);
            exit (-1);
          }
      }
  return 0;
}

static void BSE_NORETURN
jobclient (int jobfd)
{
  IpcSharedMem *sm = IpcSharedMem::acquire_shared (jobfd);
  Bse::StringVector tests;
  const std::string testlist = sm->get_string();
  for (const auto &line : Bse::string_split (testlist, "\n"))
    if (!line.empty())
      tests.push_back (line);
  for (int64 v = sm->counter.fetch_add (-1); v > 0; v = sm->counter.fetch_add (-1))
    {
      const size_t test_index = v - 1;
      TASSERT (test_index < tests.size());
      const int result = Bse::Test::run_test (tests[test_index]);
      if (result < 0)
        {
          Bse::printout ("  RUN…     %s\n", tests[test_index]);
          Bse::printout ("  FAIL     %s - test missing\n", tests[test_index]);
          exit (-1);
        }
    }
  IpcSharedMem::release_shared (sm, jobfd);
  DEBUG ("JOBDONE (%u)\n", Bse::this_thread_getpid());
  exit (0);
}

#include <unistd.h> // setsid
#include <sys/wait.h> // waitpid

static int
jobserver (const char *const argv0, Bse::StringVector &tests)
{
  BSE_UNUSED const pid_t pgid = setsid();       // keep server and spawned jobs in the same process group
  std::reverse (tests.begin(), tests.end());    // the IpcSharedMem counter is decremented
  const std::string testlist = Bse::string_join ("\n", tests);
  int fd = -1;
  IpcSharedMem *sm = IpcSharedMem::create_shared (testlist, &fd, tests.size());
  if (fd < 0 || !sm)
    die ("failed to create shared memory segment: %s", Bse::strerror (errno));
  DEBUG ("jobserver: pid=%u\n", Bse::this_thread_getpid());
  const size_t n_jobs = std::max (1, Bse::this_thread_online_cpus());
  std::vector<pid_t> jobs;
  for (size_t i = 0; i < n_jobs; i++)
    if (sm->counter > 0)        // avoid spawning jobs if there's no work
      {
        const pid_t child = fork();
        if (child == 0)
          {
            execl (argv0, argv0, "--jobfd", Bse::string_from_int (fd).c_str(), NULL);
            die ("failed to execl(\"%s\"): %s", argv0, Bse::strerror (errno));
          }
        else if (child < 0)
          {
            DEBUG ("%s: failed to fork: %s\n", argv0, Bse::strerror (errno));
          }
        else
          jobs.push_back (child);
      }
  int serverstatus = 0;
  while (jobs.size())
    {
      int wstatus = 0;
      const int pid = waitpid (-1, &wstatus, 0);
      if (pid < 0)
        {
          DEBUG ("%s: waitpid(%d) failed: %s\n", argv0, pid, Bse::strerror (errno));
          if (errno == ECHILD)
            abort(); // lost track of jobs
          continue;
        }
      const int exitstatus = WIFEXITED (wstatus) ? WEXITSTATUS (wstatus) :
                             WIFSIGNALED (wstatus) ? -WTERMSIG (wstatus) :
                             -128;
      auto it = std::find (jobs.begin(), jobs.end(), pid);
      if (it == jobs.end())
        DEBUG ("%s: orphan (%d) exited: %d\n", argv0, pid, exitstatus);
      else
        {
          jobs.erase (it);
          if (!serverstatus)
            serverstatus = exitstatus;
          DEBUG ("%s: child (%d) exited: %d\n", argv0, pid, exitstatus);
        }
    }
  const ssize_t remaining_tests = sm->counter;
  TASSERT (remaining_tests <= 0);
  IpcSharedMem::destroy_shared (sm, fd);
  return serverstatus;
}
<commit_msg>TESTS: suite1-main: explicitely print exit status<commit_after>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
#include <bse/testing.hh>
#include <bse/bse.hh>
#include <bse/bsemain.hh> // FIXME: bse_init_test
#include "ipc.hh"

#define DEBUG(...)              do { break; Bse::printerr (__VA_ARGS__); } while (0)

static int                      jobserver (const char *const argv0, Bse::StringVector &tests);
static void BSE_NORETURN        jobclient (int jobfd);

static void
print_int_ring (SfiRing *ring)
{
  SfiRing *node;
  TNOTE ("{");
  for (node = ring; node; node = sfi_ring_walk (node, ring))
    TNOTE ("%c", char (size_t (node->data)));
  TNOTE ("}");
}

static gint
ints_cmp (gconstpointer d1,
	  gconstpointer d2,
          gpointer      data)
{
  size_t i1 = size_t (d1);
  size_t i2 = size_t (d2);
  return i1 < i2 ? -1 : i1 > i2;
}

static void
test_sfi_ring (void)
{
  gint data_array[][64] = {
    { 0, },
    { 1, 'a', },
    { 2, 'a', 'a', },
    { 2, 'a', 'b', },
    { 2, 'z', 'a', },
    { 3, 'a', 'c', 'z' },
    { 3, 'a', 'z', 'c' },
    { 3, 'c', 'a', 'z' },
    { 3, 'z', 'c', 'a' },
    { 3, 'a', 'a', 'a' },
    { 3, 'a', 'a', 'z' },
    { 3, 'a', 'z', 'a' },
    { 3, 'z', 'a', 'a' },
    { 10, 'g', 's', 't', 'y', 'x', 'q', 'i', 'n', 'j', 'a' },
    { 15, 'w', 'k', 't', 'o', 'c', 's', 'j', 'd', 'd', 'q', 'p', 'v', 'q', 'r', 'a' },
    { 26, 'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm'
      ,   'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a', },
  };

  for (uint n = 0; n < G_N_ELEMENTS (data_array); n++)
    {
      uint l = data_array[n][0];
      SfiRing *ring = NULL;
      for (uint i = 1; i <= l; i++)
	ring = sfi_ring_append (ring, (void*) size_t (data_array[n][i]));
      TNOTE ("source: ");
      print_int_ring (ring);
      ring = sfi_ring_sort (ring, ints_cmp, NULL);
      TNOTE (" sorted: ");
      print_int_ring (ring);
      TNOTE ("\n");
      sfi_ring_free (ring);
    }
}
TEST_ADD (test_sfi_ring);

static Bse::ServerS bse_server;

static void
bench_aida()
{
  using namespace Bse;
  double calls = 0, slowest = 0, fastest = 9e+9;
  for (uint j = 0; j < 37; j++)
    {
      bse_server.test_counter_set (0);
      const int count = 2999;
      const uint64_t ts0 = timestamp_benchmark();
      for (int i = 0; i < count; i++)
        bse_server.test_counter_inc_fetch ();
      const uint64 ts1 = timestamp_benchmark();
      TASSERT (bse_server.test_counter_get() == count);
      double t0 = ts0 / 1000000000.;
      double t1 = ts1 / 1000000000.;
      double call1 = (t1 - t0) / count;
      slowest = MAX (slowest, call1 * 1000000.);
      fastest = MIN (fastest, call1 * 1000000.);
      double this_calls = 1 / call1;
      calls = MAX (calls, this_calls);
    }
  double err = (slowest - fastest) / slowest;
  printout ("  BENCH    Aida: %g calls/s; fastest: %.2fus; slowest: %.2fus; err: %.2f%%\n",
            calls, fastest, slowest, err * 100);
}

int
main (int   argc,
      char *argv[])
{
  const Bse::StringVector args = Bse::cstrings_to_vector ("stand-alone=1", "wave-chunk-padding=1", NULL);
  // "wave-chunk-big-pad=2", "dcache-block-size=16"

  Bse::StringVector test_names;
  Bse::Test::TestEntries test_entries;
  int64 jobs = 0;
  int jobfd = -1;
  int64 testflags = 0;

  for (ssize_t i = 1; i < argc; i++)
    if (argv[i])
      {
        if (std::string ("--aida-bench") == argv[i])
          {
            Bse::init_async (&argc, argv, argv[0], args);
            bse_server = Bse::init_server_instance();
            bench_aida();
            return 0;
          }
        else if (std::string ("--broken") == argv[i])
          {
            testflags |= Bse::Test::BROKEN;
          }
        else if (std::string ("--slow") == argv[i])
          {
            testflags |= Bse::Test::SLOW;
          }
        else if (std::string ("--bench") == argv[i])
          {
            testflags |= Bse::Test::BENCH;
          }
        else if (std::string ("--jobfd") == argv[i] && i + 1 < argc)
          {
            jobfd = Bse::string_to_int (argv[++i]);
          }
        else if (std::string ("-j") == argv[i])
          {
            jobs = 1;
          }
        else if ('-' == argv[i][0])
          {
            Bse::printerr ("%s: unknown option: %s\n", argv[0], argv[i]);
            return 7;
          }
        else
          {
            test_names.push_back (argv[i]);
            test_entries.push_back (Bse::Test::TestEntry (argv[i]));
          }
      }

  bse_init_test (&argc, argv, args);

  if (jobfd != -1)
    jobclient (jobfd);  // noreturn

  if (test_entries.size() == 0)
    test_entries = Bse::Test::list_tests();

  int serverstatus = 0;
  if (jobs)
    {
      Bse::StringVector tests;
      for (const Bse::Test::TestEntry &entry : test_entries)
        if (0 == (entry.flags & ~testflags))
          tests.push_back (entry.ident);
      serverstatus = jobserver (argv[0], tests);
    }
  else
    for (Bse::Test::TestEntry entry : test_entries)
      if (0 == (entry.flags & ~testflags))
        {
          const int result = Bse::Test::run_test (entry.ident);
          if (result < 0)
            {
              Bse::printout ("  RUN…     %s\n", entry.ident);
              Bse::printout ("  FAIL     %s - test missing\n", entry.ident);
              serverstatus = -1;
              break;
            }
        }
  Bse::printout ("  EXIT     %d - %s\n", serverstatus, serverstatus ? "FAIL" : "OK");
  return serverstatus;
}

static void BSE_NORETURN
jobclient (int jobfd)
{
  IpcSharedMem *sm = IpcSharedMem::acquire_shared (jobfd);
  Bse::StringVector tests;
  const std::string testlist = sm->get_string();
  for (const auto &line : Bse::string_split (testlist, "\n"))
    if (!line.empty())
      tests.push_back (line);
  for (int64 v = sm->counter.fetch_add (-1); v > 0; v = sm->counter.fetch_add (-1))
    {
      const size_t test_index = v - 1;
      TASSERT (test_index < tests.size());
      const int result = Bse::Test::run_test (tests[test_index]);
      if (result < 0)
        {
          Bse::printout ("  RUN…     %s\n", tests[test_index]);
          Bse::printout ("  FAIL     %s - test missing\n", tests[test_index]);
          exit (-1);
        }
    }
  IpcSharedMem::release_shared (sm, jobfd);
  DEBUG ("JOBDONE (%u)\n", Bse::this_thread_getpid());
  exit (0);
}

#include <unistd.h> // setsid
#include <sys/wait.h> // waitpid

static int
jobserver (const char *const argv0, Bse::StringVector &tests)
{
  BSE_UNUSED const pid_t pgid = setsid();       // keep server and spawned jobs in the same process group
  std::reverse (tests.begin(), tests.end());    // the IpcSharedMem counter is decremented
  const std::string testlist = Bse::string_join ("\n", tests);
  int fd = -1;
  IpcSharedMem *sm = IpcSharedMem::create_shared (testlist, &fd, tests.size());
  if (fd < 0 || !sm)
    die ("failed to create shared memory segment: %s", Bse::strerror (errno));
  DEBUG ("jobserver: pid=%u\n", Bse::this_thread_getpid());
  const size_t n_jobs = std::max (1, Bse::this_thread_online_cpus());
  std::vector<pid_t> jobs;
  for (size_t i = 0; i < n_jobs; i++)
    if (sm->counter > 0)        // avoid spawning jobs if there's no work
      {
        const pid_t child = fork();
        if (child == 0)
          {
            execl (argv0, argv0, "--jobfd", Bse::string_from_int (fd).c_str(), NULL);
            die ("failed to execl(\"%s\"): %s", argv0, Bse::strerror (errno));
          }
        else if (child < 0)
          {
            DEBUG ("%s: failed to fork: %s\n", argv0, Bse::strerror (errno));
          }
        else
          jobs.push_back (child);
      }
  int serverstatus = 0;
  while (jobs.size())
    {
      int wstatus = 0;
      const int pid = waitpid (-1, &wstatus, 0);
      if (pid < 0)
        {
          DEBUG ("%s: waitpid(%d) failed: %s\n", argv0, pid, Bse::strerror (errno));
          if (errno == ECHILD)
            abort(); // lost track of jobs
          continue;
        }
      const int exitstatus = WIFEXITED (wstatus) ? WEXITSTATUS (wstatus) :
                             WIFSIGNALED (wstatus) ? -WTERMSIG (wstatus) :
                             -128;
      auto it = std::find (jobs.begin(), jobs.end(), pid);
      if (it == jobs.end())
        DEBUG ("%s: orphan (%d) exited: %d\n", argv0, pid, exitstatus);
      else
        {
          jobs.erase (it);
          if (!serverstatus)
            serverstatus = exitstatus;
          DEBUG ("%s: child (%d) exited: %d\n", argv0, pid, exitstatus);
        }
    }
  const ssize_t remaining_tests = sm->counter;
  TASSERT (remaining_tests <= 0);
  IpcSharedMem::destroy_shared (sm, fd);
  return serverstatus;
}
<|endoftext|>


<commit_before><commit_msg>o3: handle fetch with no active threads correctly. This situation can arise now on the first fetch cycle after the last active thread is halted.  It seems easy enough to deal with when it happens rather than trying to avoid it.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2018 Matthew J. Smith and Overkit contributors
// License: MIT (http://opensource.org/licenses/MIT)

#include "ovk/extras-c/XINTOUT.h"

#include "ovk/extras-c/Constants.h"
#include "ovk/extras-c/Global.h"
#include "ovk/extras/Constants.hpp"
#include "ovk/extras/Global.hpp"
#include "ovk/extras/XINTOUT.hpp"
#include "ovk/core-c/Constants.h"
#include "ovk/core-c/Global.h"
#include "ovk/core/Debug.hpp"

#include <string>

ovk_error ovkImportXINTOUT(ovk_domain *Domain, const char *HOPath, const char *XPath,
  int ReadGranularityAdjust, MPI_Info MPIInfo) {

  OVK_DEBUG_ASSERT(Domain, "Invalid exchange pointer.");
  OVK_DEBUG_ASSERT(HOPath, "Invalid ho path pointer.");
  OVK_DEBUG_ASSERT(XPath, "Invalid x path pointer.");

  auto &DomainCPP = *reinterpret_cast<ovk::domain *>(Domain);
  std::string HOPathCPP = HOPath;
  std::string XPathCPP = XPath;

  ovk::error Error = ovk::ImportXINTOUT(DomainCPP, HOPathCPP, XPathCPP, ReadGranularityAdjust,
    MPIInfo);

  return ovk_error(Error);

}

ovk_error ovkExportXINTOUT(const ovk_domain *Domain, const char *HOPath, const char *XPath,
  ovk_xintout_format Format, ovk_endian Endian, int WriteGranularityAdjust, MPI_Info MPIInfo) {

  OVK_DEBUG_ASSERT(Domain, "Invalid exchange pointer.");
  OVK_DEBUG_ASSERT(HOPath, "Invalid ho path pointer.");
  OVK_DEBUG_ASSERT(XPath, "Invalid x path pointer.");

  auto &DomainCPP = *reinterpret_cast<const ovk::domain *>(Domain);
  std::string HOPathCPP = HOPath;
  std::string XPathCPP = XPath;

  ovk::error Error = ovk::ExportXINTOUT(DomainCPP, HOPathCPP, XPathCPP, ovk::xintout_format(Format),
    ovk::endian(Endian), WriteGranularityAdjust, MPIInfo);

  return ovk_error(Error);

}
<commit_msg>added missing extern C<commit_after>// Copyright (c) 2018 Matthew J. Smith and Overkit contributors
// License: MIT (http://opensource.org/licenses/MIT)

#include "ovk/extras-c/XINTOUT.h"

#include "ovk/extras-c/Constants.h"
#include "ovk/extras-c/Global.h"
#include "ovk/extras/Constants.hpp"
#include "ovk/extras/Global.hpp"
#include "ovk/extras/XINTOUT.hpp"
#include "ovk/core-c/Constants.h"
#include "ovk/core-c/Global.h"
#include "ovk/core/Debug.hpp"

#include <string>

extern "C" {

ovk_error ovkImportXINTOUT(ovk_domain *Domain, const char *HOPath, const char *XPath,
  int ReadGranularityAdjust, MPI_Info MPIInfo) {

  OVK_DEBUG_ASSERT(Domain, "Invalid exchange pointer.");
  OVK_DEBUG_ASSERT(HOPath, "Invalid ho path pointer.");
  OVK_DEBUG_ASSERT(XPath, "Invalid x path pointer.");

  auto &DomainCPP = *reinterpret_cast<ovk::domain *>(Domain);
  std::string HOPathCPP = HOPath;
  std::string XPathCPP = XPath;

  ovk::error Error = ovk::ImportXINTOUT(DomainCPP, HOPathCPP, XPathCPP, ReadGranularityAdjust,
    MPIInfo);

  return ovk_error(Error);

}

ovk_error ovkExportXINTOUT(const ovk_domain *Domain, const char *HOPath, const char *XPath,
  ovk_xintout_format Format, ovk_endian Endian, int WriteGranularityAdjust, MPI_Info MPIInfo) {

  OVK_DEBUG_ASSERT(Domain, "Invalid exchange pointer.");
  OVK_DEBUG_ASSERT(HOPath, "Invalid ho path pointer.");
  OVK_DEBUG_ASSERT(XPath, "Invalid x path pointer.");

  auto &DomainCPP = *reinterpret_cast<const ovk::domain *>(Domain);
  std::string HOPathCPP = HOPath;
  std::string XPathCPP = XPath;

  ovk::error Error = ovk::ExportXINTOUT(DomainCPP, HOPathCPP, XPathCPP, ovk::xintout_format(Format),
    ovk::endian(Endian), WriteGranularityAdjust, MPIInfo);

  return ovk_error(Error);

}

}
<|endoftext|>


<commit_before>#include <mantella_bits/helper/setTheory.hpp>

// C++ standard library
#include <algorithm>

namespace mant {
  std::vector<arma::Col<arma::uword>> getCombinations(
      const arma::uword numberOfElements,
      const arma::uword combinationSize) {
    std::vector<arma::Col<arma::uword>> combinations;

    std::vector<int> bitmask(numberOfElements);
    std::fill(bitmask.begin(), bitmask.begin() + combinationSize, 1);
    do {
      arma::Col<arma::uword> combination(combinationSize);
      arma::uword k = 0;
      for (arma::uword n = 0; n < numberOfElements; ++n) {
        if (bitmask.at(n)) {
          combination(k++) = n;
        }
      }

      combinations.push_back(combination);
    } while (std::prev_permutation(bitmask.begin(), bitmask.end()));

    return combinations;
  }

  std::vector<std::pair<arma::Col<arma::uword>, arma::Col<arma::uword>>> getTwoSetsPartitions(
      const arma::uword numberOfElements) {
    arma::Col<arma::uword> elements = arma::linspace<arma::Col<arma::uword>>(0, numberOfElements - 1, numberOfElements);

    std::vector<std::pair<arma::Col<arma::uword>, arma::Col<arma::uword>>> partitions;

    for(arma::uword n = 1; n <= std::floor(static_cast<double>(numberOfElements) / 2.0); ++n) {
      arma::Col<arma::uword> firstSet = elements.head(n);
      arma::Col<arma::uword> secondSet = elements.tail(elements.n_elem - n);

      partitions.push_back({firstSet, secondSet});

      arma::Col<arma::uword> counter(n, arma::fill::zeros);
      arma::uword shiftedIndex = counter.n_elem;

      arma::uword lastIndex = 0;
      if(firstSet.n_elem == secondSet.size()) {
        lastIndex = 1;
      }

        std::iter_swap(firstSet.begin() + index, secondSet.begin() + counter(index));
      while (shiftedIndex > lastIndex) {
        const arma::uword& index = shiftedIndex - 1;

        partitions.push_back({firstSet, secondSet});

        if(counter(index) < secondSet.n_elem - 1) {
          counter.tail(counter.n_elem - index).fill(counter(index) + 1);
          shiftedIndex = counter.n_elem;
        } else {
          --shiftedIndex;
        }
      }
    }

    return partitions;
  }
}
<commit_msg>"Better" comparision<commit_after>#include <mantella_bits/helper/setTheory.hpp>

// C++ standard library
#include <algorithm>

namespace mant {
  std::vector<arma::Col<arma::uword>> getCombinations(
      const arma::uword numberOfElements,
      const arma::uword combinationSize) {
    std::vector<arma::Col<arma::uword>> combinations;

    std::vector<int> bitmask(numberOfElements);
    std::fill(bitmask.begin(), bitmask.begin() + combinationSize, 1);
    do {
      arma::Col<arma::uword> combination(combinationSize);
      arma::uword k = 0;
      for (arma::uword n = 0; n < numberOfElements; ++n) {
        if (bitmask.at(n) > 0) {
          combination(k++) = n;
        }
      }

      combinations.push_back(combination);
    } while (std::prev_permutation(bitmask.begin(), bitmask.end()));

    return combinations;
  }

  std::vector<std::pair<arma::Col<arma::uword>, arma::Col<arma::uword>>> getTwoSetsPartitions(
      const arma::uword numberOfElements) {
    arma::Col<arma::uword> elements = arma::linspace<arma::Col<arma::uword>>(0, numberOfElements - 1, numberOfElements);

    std::vector<std::pair<arma::Col<arma::uword>, arma::Col<arma::uword>>> partitions;

    for(arma::uword n = 1; n <= std::floor(static_cast<double>(numberOfElements) / 2.0); ++n) {
      arma::Col<arma::uword> firstSet = elements.head(n);
      arma::Col<arma::uword> secondSet = elements.tail(elements.n_elem - n);

      partitions.push_back({firstSet, secondSet});

      arma::Col<arma::uword> counter(n, arma::fill::zeros);
      arma::uword shiftedIndex = counter.n_elem;

      arma::uword lastIndex = 0;
      if(firstSet.n_elem == secondSet.size()) {
        lastIndex = 1;
      }

        std::iter_swap(firstSet.begin() + index, secondSet.begin() + counter(index));
      while (shiftedIndex > lastIndex) {
        const arma::uword& index = shiftedIndex - 1;

        partitions.push_back({firstSet, secondSet});

        if(counter(index) < secondSet.n_elem - 1) {
          counter.tail(counter.n_elem - index).fill(counter(index) + 1);
          shiftedIndex = counter.n_elem;
        } else {
          --shiftedIndex;
        }
      }
    }

    return partitions;
  }
}
<|endoftext|>


<commit_before>//for pendulum-test

#include <cmath>
#include <cstdlib>
#include <ctime>
#include "StateSpace.h"
#include "Action.h"
#include "PriorityQueue.h"
#include "State.h"

//function to calculate a temperature for the select action function as a function of time
double temperature();

//function to select next action
Action * selectAction(PriorityQueue<Action *,double>& a_queue);

//function to update a q value
void updateQ(StateSpace & space, Action & action, State & new_state, State & old_state, double alpha, double gamma);

int main()
{
	//learning factor
	const double alpha=0.5;
	//discount factor
	const double gamma=0.5;

	//seed rng
	std::srand(std::time(NULL));

	//create pointers to the possible actions as well as a pointer to hold the chosen action
	Action* chosen_action;
	Action* actions[3];
	actions[0]=new Action(INCREASE);
	actions[1]=new Action(DECREASE);
	actions[2]=new Action(SAME);

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<Action,double> initiator_queue(MAX);
	ititiator_queue.enqueueWithPriority(actions[0],0);
	ititiator_queue.enqueueWithPriority(actions[1],0);
	ititiator_queue.enqueueWithPriority(actions[2],0);

	//create the state space
	StateSpace space(100,50,torque,initiator_queue);

	//state objects
	State current_state(0,0,INCREASE);
	State old_state(0,0,INCREASE);

	//timing variables
	double loop_start_time;
	while(true)
	{
		loop_start_time=std::time(NULL);

		current_state.theta=getAngle();
		current_state.theta_dot=getVelocity();
		current_state.robot_state=chosen_action.action;

		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		old_state=current_state;

		chosen_action=selectAction(space[current_state]);

		chosen_action.execute();

		if(std::time(NULL)-loop_start_time>250); //wait for set time
	}

	delete actions[0];
	delete actions[1];

	return 1;
}

double temperature()
{
	return std::time(NULL);
}

//function is fed with a priority queue of action-values
//generates Boltzmann distribution of these action-values
//and selects an action based on probabilities
Action * selectAction(PriorityQueue<Action *,double>& a_queue)
{
	typedef PriorityQueue<Action *,double> PQ;
	typedef std::vector< std::pair<Action *, double> > Vec_Pair;
	typedef std::pair<Action *, double> Pair;

	double sum= 0;
	int i = 0;

	int size = a_queue.getSize();
	Vec_Pair action_vec(size);

	//Calculate partition function by iterating over action-values
	for(PQ::const_iterator iter = a_queue.begin(),end=a_queue.end(); iter < end; ++iter)
	{
		sum += std::exp((iter->second)/temperature());
	}
	//Calculate boltzmann factors for action-values
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
	    it->first = a_queue[i].first;
	    it->second = std::exp(a_queue[i].second /temperature()) / sum;
	    ++i;
	}

	//calculate cumulative probability distribution
	for(std::vector< std::pair<int, double> >::iterator it1 = action_vec.begin()++,it2 = action_vec.begin(),end=action_vec.end(); it < end; ++it1,++it2)
	{
	    it1->second += it2->second;
	}

	//generate RN between 0 and 1
	double rand_num = (double)rand()/ (RAND_MAX);

	//select action based on probability
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
		//if RN falls within cumulative probability bin return the corresponding action
		if(rand_num < it->second)return it->first;
	}

	return NULL; //note that this line should never be reached
}

void updateQ(StateSpace & space, Action & action, State & new_state, State & old_state, double alpha, double gamma)
{
    //oldQ value reference
    double oldQ = space[old_state].search(action).second;

    //reward given to current state
    double R = new_state.getReward();

    //optimal Q value for new state i.e. first element
    double maxQ = space[current_state].peekFront().second;

    //new Q value determined by Q learning algorithm
    double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

    space[old_state].changePriority(action, newQ);
}
<commit_msg>Delete Main3.cpp<commit_after><|endoftext|>


<commit_before>#include "cubeb/cubeb.h"
#include <atomic>
#include <cassert>
#include <cmath>
#include <cstdarg>
#include <cstring>
#include <iostream>
#ifdef _WIN32
#include <objbase.h> // Used by CoInitialize()
#endif

#ifndef M_PI
#define M_PI 3.14159263
#endif

// Default values if none specified
#define DEFAULT_RATE 44100
#define DEFAULT_CHANNELS 2

static const char* state_to_string(cubeb_state state) {
  switch (state) {
    case CUBEB_STATE_STARTED:
      return "CUBEB_STATE_STARTED";
    case CUBEB_STATE_STOPPED:
      return "CUBEB_STATE_STOPPED";
    case CUBEB_STATE_DRAINED:
      return "CUBEB_STATE_DRAINED";
    case CUBEB_STATE_ERROR:
      return "CUBEB_STATE_ERROR";
    default:
      return "Undefined state";
  }
}

void print_log(const char* msg, ...) {
  va_list args;
  va_start(args, msg);
  vprintf(msg, args);
  va_end(args);
}

class cubeb_client final {
public:
  cubeb_client() {}
  ~cubeb_client() {}

  bool init(char const * backend_name = nullptr);
  bool init_stream();
  bool start_stream() const;
  bool stop_stream() const;
  bool destroy_stream() const;
  bool destroy();
  bool activate_log(bool active);

  long user_data_cb(cubeb_stream* stm, void* user, const void* input_buffer,
                    void* output_buffer, long nframes);

  void user_state_cb(cubeb_stream* stm, void* user, cubeb_state state);

  bool register_device_collection_changed(cubeb_device_type devtype) const;
  bool unregister_device_collection_changed(cubeb_device_type devtype) const;

  cubeb_stream_params output_params = {};
  cubeb_stream_params input_params = {};

private:
  bool has_input() { return input_params.rate != 0; }
  bool has_output() { return output_params.rate != 0; }

  cubeb* context = nullptr;

  cubeb_stream* stream = nullptr;
  cubeb_devid output_device = nullptr;
  cubeb_devid input_device = nullptr;

  /* Accessed only from client and audio thread. */
  std::atomic<uint32_t> _rate = {0};
  std::atomic<uint32_t> _channels = {0};

  /* Accessed only from audio thread. */
  uint32_t _total_frames = 0;
};

bool cubeb_client::init(char const * backend_name) {
  int rv = cubeb_init(&context, "Cubeb Test Application", nullptr);
  if (rv != CUBEB_OK) {
    fprintf(stderr, "Could not init cubeb\n");
    return false;
  }
  return true;
}

static long user_data_cb_s(cubeb_stream* stm, void* user,
                           const void* input_buffer, void* output_buffer,
                           long nframes) {
  assert(user);
  return static_cast<cubeb_client*>(user)->user_data_cb(stm, user, input_buffer,
                                                        output_buffer, nframes);
}

static void user_state_cb_s(cubeb_stream* stm, void* user, cubeb_state state) {
  assert(user);
  return static_cast<cubeb_client*>(user)->user_state_cb(stm, user, state);
}

void input_device_changed_callback_s(cubeb* context, void* user) {
  fprintf(stderr, "input_device_changed_callback_s\n");
}

void output_device_changed_callback_s(cubeb* context, void* user) {
  fprintf(stderr, "output_device_changed_callback_s\n");
}

void io_device_changed_callback_s(cubeb* context, void* user) {
  fprintf(stderr, "io_device_changed_callback\n");
}

bool cubeb_client::init_stream() {
  assert(has_input() || has_output());

  _rate = has_output() ? output_params.rate : input_params.rate;
  _channels = has_output() ? output_params.channels : input_params.channels;

  int rv =
      cubeb_stream_init(context, &stream, "Stream", input_device,
                        has_input() ? &input_params : nullptr, output_device,
                        has_output() ? &output_params : nullptr, 512,
                        user_data_cb_s, user_state_cb_s, this);
  if (rv != CUBEB_OK) {
    fprintf(stderr, "Could not open the stream\n");
    return false;
  }
  return true;
}

bool cubeb_client::start_stream() const {
  int rv = cubeb_stream_start(stream);
  if (rv != CUBEB_OK) {
    fprintf(stderr, "Could not start the stream\n");
    return false;
  }
  return true;
}

bool cubeb_client::stop_stream() const {
  int rv = cubeb_stream_stop(stream);
  if (rv != CUBEB_OK) {
    fprintf(stderr, "Could not stop the stream\n");
    return false;
  }
  return true;
}

bool cubeb_client::destroy_stream() const {
  cubeb_stream_destroy(stream);
  return true;
}

bool cubeb_client::destroy() {
  cubeb_destroy(context);
  return true;
}

bool cubeb_client::activate_log(bool active) {
  cubeb_log_level log_level = CUBEB_LOG_DISABLED;
  cubeb_log_callback log_callback = nullptr;
  if (active) {
    log_level = CUBEB_LOG_NORMAL;
    log_callback = print_log;
  }

  if (cubeb_set_log_callback(log_level, log_callback) != CUBEB_OK) {
    fprintf(stderr, "Set log callback failed\n");
    return false;
  }
  return true;
}

static void fill_with_sine_tone(float* buf, uint32_t num_of_frames,
                               uint32_t num_of_channels, uint32_t frame_rate,
                               uint32_t position) {
  for (uint32_t i = 0; i < num_of_frames; ++i) {
    for (uint32_t c = 0; c < num_of_channels; ++c) {
      buf[i * num_of_channels + c] =
          0.2 * sin(2 * M_PI * (i + position) * 350 / frame_rate);
      buf[i * num_of_channels + c] +=
          0.2 * sin(2 * M_PI * (i + position) * 440 / frame_rate);
    }
  }
}

long cubeb_client::user_data_cb(cubeb_stream* stm, void* user,
                                const void* input_buffer, void* output_buffer,
                                long nframes) {
  if (input_buffer && output_buffer) {
    const float* in = static_cast<const float*>(input_buffer);
    float* out = static_cast<float*>(output_buffer);
    memcpy(out, in, sizeof(float) * nframes * _channels);
  } else if (output_buffer && !input_buffer) {
    fill_with_sine_tone(static_cast<float*>(output_buffer), nframes, _channels,
                       _rate, _total_frames);
  }

  _total_frames += nframes;
  return nframes;
}

void cubeb_client::user_state_cb(cubeb_stream* stm, void* user,
                                 cubeb_state state) {
  fprintf(stderr, "state is %s\n", state_to_string(state));
}

bool cubeb_client::register_device_collection_changed(
    cubeb_device_type devtype) const {
  cubeb_device_collection_changed_callback callback = nullptr;
  if (devtype == static_cast<cubeb_device_type>(CUBEB_DEVICE_TYPE_INPUT |
                                                CUBEB_DEVICE_TYPE_OUTPUT)) {
    callback = io_device_changed_callback_s;
  } else if (devtype & CUBEB_DEVICE_TYPE_OUTPUT) {
    callback = output_device_changed_callback_s;
  } else if (devtype & CUBEB_DEVICE_TYPE_INPUT) {
    callback = input_device_changed_callback_s;
  }
  int r = cubeb_register_device_collection_changed(
            context, devtype, callback, nullptr);
  if (r != CUBEB_OK) {
    return false;
  }
  return true;
}

bool cubeb_client::unregister_device_collection_changed(
    cubeb_device_type devtype) const {
  int r = cubeb_register_device_collection_changed(
            context, devtype, nullptr, nullptr);
  if (r != CUBEB_OK) {
    return false;
  }
  return true;
}

enum play_mode {
  RECORD,
  PLAYBACK,
  DUPLEX,
  COLLECTION_CHANGE,
};

struct operation_data {
  play_mode pm;
  uint32_t rate;
  cubeb_device_type collection_device_type;
};

void print_help() {
  const char * msg =
    "p: start a initialized stream\n"
    "s: stop a started stream\n"
    "i: change device type to input\n"
    "o: change device type to output\n"
    "a: change device type to input and output\n"
    "k: change device type to unknown\n"
    "r: register device collection changed callback for the current device type\n"
    "u: unregister device collection changed callback for the current device type\n"
    "q: quit\n"
    "h: print this message\n";
  fprintf(stderr, "%s\n", msg);
}

bool choose_action(const cubeb_client& cl, operation_data * op, char c) {
  while (c == 10 || c == 32) {
    // Consume "enter and "space"
    c = getchar();
  }

  if (c == 'q') {
    if (op->pm == PLAYBACK || op->pm == RECORD || op->pm == DUPLEX) {
      bool res = cl.stop_stream();
      if (!res) {
        fprintf(stderr, "stop_stream failed\n");
      }
      res = cl.destroy_stream();
      if (!res) {
        fprintf(stderr, "destroy_stream failed\n");
      }
    } else if (op->pm == COLLECTION_CHANGE) {
      bool res = cl.unregister_device_collection_changed(op->collection_device_type);
      if (!res) {
        fprintf(stderr, "unregister_device_collection_changed failed\n");
      }
    }
    return false; // exit the loop
  } else if (c == 'h') {
    print_help();
  } else if (c == 'p') {
    bool res = cl.start_stream();
    if (res) {
      fprintf(stderr, "start_stream succeed\n");
    } else {
      fprintf(stderr, "start_stream failed\n");
    }
  } else if (c == 's') {
    bool res = cl.stop_stream();
    if (res) {
      fprintf(stderr, "stop_stream succeed\n");
    } else {
      fprintf(stderr, "stop_stream failed\n");
    }
  } else if (c == 'i') {
    op->collection_device_type = CUBEB_DEVICE_TYPE_INPUT;
    fprintf(stderr, "collection device type changed to INPUT\n");
  } else if (c == 'o') {
    op->collection_device_type = CUBEB_DEVICE_TYPE_OUTPUT;
    fprintf(stderr, "collection device type changed to OUTPUT\n");
  } else if (c == 'a') {
    op->collection_device_type = static_cast<cubeb_device_type>(CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT);
    fprintf(stderr, "collection device type changed to INPUT | OUTPUT\n");
  } else if (c == 'k') {
    op->collection_device_type = CUBEB_DEVICE_TYPE_UNKNOWN;
    fprintf(stderr, "collection device type changed to UNKNOWN\n");
  } else if (c == 'r') {
    bool res = cl.register_device_collection_changed(op->collection_device_type);
    if (res) {
      fprintf(stderr, "register_device_collection_changed succeed\n");
    } else {
      fprintf(stderr, "register_device_collection_changed failed\n");
    }
  } else if (c == 'u') {
    bool res = cl.unregister_device_collection_changed(op->collection_device_type);
    if (res) {
      fprintf(stderr, "unregister_device_collection_changed succeed\n");
    } else {
      fprintf(stderr, "unregister_device_collection_changed failed\n");
    }
  } else {
    fprintf(stderr, "Error: %c is not a valid entry\n", c);
  }

  return true; // Loop up
}

int main(int argc, char* argv[]) {
#ifdef _WIN32
  CoInitialize(nullptr);
#endif

  operation_data op;
  op.pm = PLAYBACK;
  if (argc > 1) {
    if ('r' == argv[1][0]) {
      op.pm = RECORD;
    } else if ('p' == argv[1][0]) {
      op.pm = PLAYBACK;
    } else if ('d' == argv[1][0]) {
      op.pm = DUPLEX;
    } else if ('c' == argv[1][0]) {
      op.pm = COLLECTION_CHANGE;
    }
  }
  op.rate = DEFAULT_RATE;
  if (argc > 2) {
    op.rate = strtoul(argv[2], NULL, 0);
  }

  bool res = false;
  cubeb_client cl;
  cl.activate_log(true);
  cl.init();

  op.collection_device_type = CUBEB_DEVICE_TYPE_UNKNOWN;
  fprintf(stderr, "collection device type is UNKNOWN\n");
  if (op.pm == COLLECTION_CHANGE) {
    op.collection_device_type = CUBEB_DEVICE_TYPE_OUTPUT;
    fprintf(stderr, "collection device type changed to OUTPUT\n");
    res = cl.register_device_collection_changed(op.collection_device_type);
    if (res) {
      fprintf(stderr, "register_device_collection_changed succeed\n");
    } else {
      fprintf(stderr, "register_device_collection_changed failed\n");
    }
  } else {
    if (op.pm == PLAYBACK || op.pm == DUPLEX) {
      cl.output_params = {CUBEB_SAMPLE_FLOAT32NE, op.rate, DEFAULT_CHANNELS,
                          CUBEB_LAYOUT_UNDEFINED, CUBEB_STREAM_PREF_NONE};
    }
    if (op.pm == RECORD || op.pm == DUPLEX) {
      cl.input_params = {CUBEB_SAMPLE_FLOAT32NE, op.rate, DEFAULT_CHANNELS,
                         CUBEB_LAYOUT_UNDEFINED, CUBEB_STREAM_PREF_NONE};
    }
    res = cl.init_stream();
    if (!res) {
      fprintf(stderr, "stream_init failed\n");
      return -1;
    }
    fprintf(stderr, "stream_init succeed\n");

    res = cl.start_stream();
    if (res) {
      fprintf(stderr, "stream_start succeed\n");
    } else {
      fprintf(stderr, "stream_init failed\n");
    }
  }

  // User input
  do {
    fprintf(stderr, "press `q` to abort or `h` for help\n");
  } while (choose_action(cl, &op, getchar()));

  cl.destroy();

  return 0;
}
<commit_msg>cubeb-test: add options to enable/disable logs.<commit_after>#include "cubeb/cubeb.h"
#include <atomic>
#include <cassert>
#include <cmath>
#include <cstdarg>
#include <cstring>
#include <iostream>
#ifdef _WIN32
#include <objbase.h> // Used by CoInitialize()
#endif

#ifndef M_PI
#define M_PI 3.14159263
#endif

// Default values if none specified
#define DEFAULT_RATE 44100
#define DEFAULT_CHANNELS 2

static const char* state_to_string(cubeb_state state) {
  switch (state) {
    case CUBEB_STATE_STARTED:
      return "CUBEB_STATE_STARTED";
    case CUBEB_STATE_STOPPED:
      return "CUBEB_STATE_STOPPED";
    case CUBEB_STATE_DRAINED:
      return "CUBEB_STATE_DRAINED";
    case CUBEB_STATE_ERROR:
      return "CUBEB_STATE_ERROR";
    default:
      return "Undefined state";
  }
}

void print_log(const char* msg, ...) {
  va_list args;
  va_start(args, msg);
  vprintf(msg, args);
  va_end(args);
}

class cubeb_client final {
public:
  cubeb_client() {}
  ~cubeb_client() {}

  bool init(char const * backend_name = nullptr);
  bool init_stream();
  bool start_stream() const;
  bool stop_stream() const;
  bool destroy_stream() const;
  bool destroy();
  bool activate_log(cubeb_log_level log_level) const;

  long user_data_cb(cubeb_stream* stm, void* user, const void* input_buffer,
                    void* output_buffer, long nframes);

  void user_state_cb(cubeb_stream* stm, void* user, cubeb_state state);

  bool register_device_collection_changed(cubeb_device_type devtype) const;
  bool unregister_device_collection_changed(cubeb_device_type devtype) const;

  cubeb_stream_params output_params = {};
  cubeb_stream_params input_params = {};

private:
  bool has_input() { return input_params.rate != 0; }
  bool has_output() { return output_params.rate != 0; }

  cubeb* context = nullptr;

  cubeb_stream* stream = nullptr;
  cubeb_devid output_device = nullptr;
  cubeb_devid input_device = nullptr;

  /* Accessed only from client and audio thread. */
  std::atomic<uint32_t> _rate = {0};
  std::atomic<uint32_t> _channels = {0};

  /* Accessed only from audio thread. */
  uint32_t _total_frames = 0;
};

bool cubeb_client::init(char const * backend_name) {
  int rv = cubeb_init(&context, "Cubeb Test Application", nullptr);
  if (rv != CUBEB_OK) {
    fprintf(stderr, "Could not init cubeb\n");
    return false;
  }
  return true;
}

static long user_data_cb_s(cubeb_stream* stm, void* user,
                           const void* input_buffer, void* output_buffer,
                           long nframes) {
  assert(user);
  return static_cast<cubeb_client*>(user)->user_data_cb(stm, user, input_buffer,
                                                        output_buffer, nframes);
}

static void user_state_cb_s(cubeb_stream* stm, void* user, cubeb_state state) {
  assert(user);
  return static_cast<cubeb_client*>(user)->user_state_cb(stm, user, state);
}

void input_device_changed_callback_s(cubeb* context, void* user) {
  fprintf(stderr, "input_device_changed_callback_s\n");
}

void output_device_changed_callback_s(cubeb* context, void* user) {
  fprintf(stderr, "output_device_changed_callback_s\n");
}

void io_device_changed_callback_s(cubeb* context, void* user) {
  fprintf(stderr, "io_device_changed_callback\n");
}

bool cubeb_client::init_stream() {
  assert(has_input() || has_output());

  _rate = has_output() ? output_params.rate : input_params.rate;
  _channels = has_output() ? output_params.channels : input_params.channels;

  int rv =
      cubeb_stream_init(context, &stream, "Stream", input_device,
                        has_input() ? &input_params : nullptr, output_device,
                        has_output() ? &output_params : nullptr, 512,
                        user_data_cb_s, user_state_cb_s, this);
  if (rv != CUBEB_OK) {
    fprintf(stderr, "Could not open the stream\n");
    return false;
  }
  return true;
}

bool cubeb_client::start_stream() const {
  int rv = cubeb_stream_start(stream);
  if (rv != CUBEB_OK) {
    fprintf(stderr, "Could not start the stream\n");
    return false;
  }
  return true;
}

bool cubeb_client::stop_stream() const {
  int rv = cubeb_stream_stop(stream);
  if (rv != CUBEB_OK) {
    fprintf(stderr, "Could not stop the stream\n");
    return false;
  }
  return true;
}

bool cubeb_client::destroy_stream() const {
  cubeb_stream_destroy(stream);
  return true;
}

bool cubeb_client::destroy() {
  cubeb_destroy(context);
  return true;
}

bool cubeb_client::activate_log(cubeb_log_level log_level) const {
  cubeb_log_callback log_callback = nullptr;
  if (log_level != CUBEB_LOG_DISABLED) {
    log_callback = print_log;
  }

  if (cubeb_set_log_callback(log_level, log_callback) != CUBEB_OK) {
    fprintf(stderr, "Set log callback failed\n");
    return false;
  }
  return true;
}

static void fill_with_sine_tone(float* buf, uint32_t num_of_frames,
                               uint32_t num_of_channels, uint32_t frame_rate,
                               uint32_t position) {
  for (uint32_t i = 0; i < num_of_frames; ++i) {
    for (uint32_t c = 0; c < num_of_channels; ++c) {
      buf[i * num_of_channels + c] =
          0.2 * sin(2 * M_PI * (i + position) * 350 / frame_rate);
      buf[i * num_of_channels + c] +=
          0.2 * sin(2 * M_PI * (i + position) * 440 / frame_rate);
    }
  }
}

long cubeb_client::user_data_cb(cubeb_stream* stm, void* user,
                                const void* input_buffer, void* output_buffer,
                                long nframes) {
  if (input_buffer && output_buffer) {
    const float* in = static_cast<const float*>(input_buffer);
    float* out = static_cast<float*>(output_buffer);
    memcpy(out, in, sizeof(float) * nframes * _channels);
  } else if (output_buffer && !input_buffer) {
    fill_with_sine_tone(static_cast<float*>(output_buffer), nframes, _channels,
                       _rate, _total_frames);
  }

  _total_frames += nframes;
  return nframes;
}

void cubeb_client::user_state_cb(cubeb_stream* stm, void* user,
                                 cubeb_state state) {
  fprintf(stderr, "state is %s\n", state_to_string(state));
}

bool cubeb_client::register_device_collection_changed(
    cubeb_device_type devtype) const {
  cubeb_device_collection_changed_callback callback = nullptr;
  if (devtype == static_cast<cubeb_device_type>(CUBEB_DEVICE_TYPE_INPUT |
                                                CUBEB_DEVICE_TYPE_OUTPUT)) {
    callback = io_device_changed_callback_s;
  } else if (devtype & CUBEB_DEVICE_TYPE_OUTPUT) {
    callback = output_device_changed_callback_s;
  } else if (devtype & CUBEB_DEVICE_TYPE_INPUT) {
    callback = input_device_changed_callback_s;
  }
  int r = cubeb_register_device_collection_changed(
            context, devtype, callback, nullptr);
  if (r != CUBEB_OK) {
    return false;
  }
  return true;
}

bool cubeb_client::unregister_device_collection_changed(
    cubeb_device_type devtype) const {
  int r = cubeb_register_device_collection_changed(
            context, devtype, nullptr, nullptr);
  if (r != CUBEB_OK) {
    return false;
  }
  return true;
}

enum play_mode {
  RECORD,
  PLAYBACK,
  DUPLEX,
  COLLECTION_CHANGE,
};

struct operation_data {
  play_mode pm;
  uint32_t rate;
  cubeb_device_type collection_device_type;
};

void print_help() {
  const char * msg =
    "0: change log level to disabled\n"
    "1: change log level to normal\n"
    "2: change log level to verbose\n"
    "p: start a initialized stream\n"
    "s: stop a started stream\n"
    "i: change device type to input\n"
    "o: change device type to output\n"
    "a: change device type to input and output\n"
    "k: change device type to unknown\n"
    "r: register device collection changed callback for the current device type\n"
    "u: unregister device collection changed callback for the current device type\n"
    "q: quit\n"
    "h: print this message\n";
  fprintf(stderr, "%s\n", msg);
}

bool choose_action(const cubeb_client& cl, operation_data * op, char c) {
  while (c == 10 || c == 32) {
    // Consume "enter and "space"
    c = getchar();
  }

  if (c == 'q') {
    if (op->pm == PLAYBACK || op->pm == RECORD || op->pm == DUPLEX) {
      bool res = cl.stop_stream();
      if (!res) {
        fprintf(stderr, "stop_stream failed\n");
      }
      res = cl.destroy_stream();
      if (!res) {
        fprintf(stderr, "destroy_stream failed\n");
      }
    } else if (op->pm == COLLECTION_CHANGE) {
      bool res = cl.unregister_device_collection_changed(op->collection_device_type);
      if (!res) {
        fprintf(stderr, "unregister_device_collection_changed failed\n");
      }
    }
    return false; // exit the loop
  } else if (c == 'h') {
    print_help();
  } else if (c == '0') {
    cl.activate_log(CUBEB_LOG_DISABLED);
    fprintf(stderr, "Log level changed to DISABLED\n");
  } else if (c == '1') {
    cl.activate_log(CUBEB_LOG_DISABLED);
    cl.activate_log(CUBEB_LOG_NORMAL);
    fprintf(stderr, "Log level changed to NORMAL\n");
  } else if (c == '2') {
    cl.activate_log(CUBEB_LOG_DISABLED);
    cl.activate_log(CUBEB_LOG_VERBOSE);
    fprintf(stderr, "Log level changed to VERBOSE\n");
  } else if (c == 'p') {
    bool res = cl.start_stream();
    if (res) {
      fprintf(stderr, "start_stream succeed\n");
    } else {
      fprintf(stderr, "start_stream failed\n");
    }
  } else if (c == 's') {
    bool res = cl.stop_stream();
    if (res) {
      fprintf(stderr, "stop_stream succeed\n");
    } else {
      fprintf(stderr, "stop_stream failed\n");
    }
  } else if (c == 'i') {
    op->collection_device_type = CUBEB_DEVICE_TYPE_INPUT;
    fprintf(stderr, "collection device type changed to INPUT\n");
  } else if (c == 'o') {
    op->collection_device_type = CUBEB_DEVICE_TYPE_OUTPUT;
    fprintf(stderr, "collection device type changed to OUTPUT\n");
  } else if (c == 'a') {
    op->collection_device_type = static_cast<cubeb_device_type>(CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT);
    fprintf(stderr, "collection device type changed to INPUT | OUTPUT\n");
  } else if (c == 'k') {
    op->collection_device_type = CUBEB_DEVICE_TYPE_UNKNOWN;
    fprintf(stderr, "collection device type changed to UNKNOWN\n");
  } else if (c == 'r') {
    bool res = cl.register_device_collection_changed(op->collection_device_type);
    if (res) {
      fprintf(stderr, "register_device_collection_changed succeed\n");
    } else {
      fprintf(stderr, "register_device_collection_changed failed\n");
    }
  } else if (c == 'u') {
    bool res = cl.unregister_device_collection_changed(op->collection_device_type);
    if (res) {
      fprintf(stderr, "unregister_device_collection_changed succeed\n");
    } else {
      fprintf(stderr, "unregister_device_collection_changed failed\n");
    }
  } else {
    fprintf(stderr, "Error: %c is not a valid entry\n", c);
  }

  return true; // Loop up
}

int main(int argc, char* argv[]) {
#ifdef _WIN32
  CoInitialize(nullptr);
#endif

  operation_data op;
  op.pm = PLAYBACK;
  if (argc > 1) {
    if ('r' == argv[1][0]) {
      op.pm = RECORD;
    } else if ('p' == argv[1][0]) {
      op.pm = PLAYBACK;
    } else if ('d' == argv[1][0]) {
      op.pm = DUPLEX;
    } else if ('c' == argv[1][0]) {
      op.pm = COLLECTION_CHANGE;
    }
  }
  op.rate = DEFAULT_RATE;
  if (argc > 2) {
    op.rate = strtoul(argv[2], NULL, 0);
  }

  bool res = false;
  cubeb_client cl;
  cl.activate_log(CUBEB_LOG_DISABLED);
  fprintf(stderr, "Log level is DISABLED\n");
  cl.init();

  op.collection_device_type = CUBEB_DEVICE_TYPE_UNKNOWN;
  fprintf(stderr, "collection device type is UNKNOWN\n");
  if (op.pm == COLLECTION_CHANGE) {
    op.collection_device_type = CUBEB_DEVICE_TYPE_OUTPUT;
    fprintf(stderr, "collection device type changed to OUTPUT\n");
    res = cl.register_device_collection_changed(op.collection_device_type);
    if (res) {
      fprintf(stderr, "register_device_collection_changed succeed\n");
    } else {
      fprintf(stderr, "register_device_collection_changed failed\n");
    }
  } else {
    if (op.pm == PLAYBACK || op.pm == DUPLEX) {
      cl.output_params = {CUBEB_SAMPLE_FLOAT32NE, op.rate, DEFAULT_CHANNELS,
                          CUBEB_LAYOUT_UNDEFINED, CUBEB_STREAM_PREF_NONE};
    }
    if (op.pm == RECORD || op.pm == DUPLEX) {
      cl.input_params = {CUBEB_SAMPLE_FLOAT32NE, op.rate, DEFAULT_CHANNELS,
                         CUBEB_LAYOUT_UNDEFINED, CUBEB_STREAM_PREF_NONE};
    }
    res = cl.init_stream();
    if (!res) {
      fprintf(stderr, "stream_init failed\n");
      return -1;
    }
    fprintf(stderr, "stream_init succeed\n");

    res = cl.start_stream();
    if (res) {
      fprintf(stderr, "stream_start succeed\n");
    } else {
      fprintf(stderr, "stream_init failed\n");
    }
  }

  // User input
  do {
    fprintf(stderr, "press `q` to abort or `h` for help\n");
  } while (choose_action(cl, &op, getchar()));

  cl.destroy();

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrTest.h"
#include <algorithm>
#include "GrBackendSurface.h"
#include "GrContextOptions.h"
#include "GrContextPriv.h"
#include "GrDrawOpAtlas.h"
#include "GrDrawingManager.h"
#include "GrGpu.h"
#include "GrGpuResourceCacheAccess.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
#include "GrRenderTargetProxy.h"
#include "GrResourceCache.h"
#include "GrSemaphore.h"
#include "GrSurfaceContextPriv.h"
#include "GrTexture.h"
#include "SkGr.h"
#include "SkImage_Gpu.h"
#include "SkMathPriv.h"
#include "SkString.h"
#include "ops/GrMeshDrawOp.h"
#include "text/GrAtlasGlyphCache.h"
#include "text/GrTextBlobCache.h"

namespace GrTest {

void SetupAlwaysEvictAtlas(GrContext* context) {
    // These sizes were selected because they allow each atlas to hold a single plot and will thus
    // stress the atlas
    int dim = GrDrawOpAtlas::kGlyphMaxDim;
    GrDrawOpAtlasConfig configs[3];
    configs[kA8_GrMaskFormat].fWidth = dim;
    configs[kA8_GrMaskFormat].fHeight = dim;
    configs[kA8_GrMaskFormat].fPlotWidth = dim;
    configs[kA8_GrMaskFormat].fPlotHeight = dim;

    configs[kA565_GrMaskFormat].fWidth = dim;
    configs[kA565_GrMaskFormat].fHeight = dim;
    configs[kA565_GrMaskFormat].fPlotWidth = dim;
    configs[kA565_GrMaskFormat].fPlotHeight = dim;

    configs[kARGB_GrMaskFormat].fWidth = dim;
    configs[kARGB_GrMaskFormat].fHeight = dim;
    configs[kARGB_GrMaskFormat].fPlotWidth = dim;
    configs[kARGB_GrMaskFormat].fPlotHeight = dim;

    context->setTextContextAtlasSizes_ForTesting(configs);
}

GrBackendTexture CreateBackendTexture(GrBackend backend, int width, int height,
                                      GrPixelConfig config, GrMipMapped mipMapped,
                                      GrBackendObject handle) {
    switch (backend) {
#ifdef SK_VULKAN
        case kVulkan_GrBackend: {
            GrVkImageInfo* vkInfo = (GrVkImageInfo*)(handle);
            SkASSERT((GrMipMapped::kYes == mipMapped) == (vkInfo->fLevelCount > 1));
            return GrBackendTexture(width, height, *vkInfo);
        }
#endif
        case kOpenGL_GrBackend: {
            GrGLTextureInfo* glInfo = (GrGLTextureInfo*)(handle);
            SkASSERT(glInfo->fFormat);
            return GrBackendTexture(width, height, mipMapped, *glInfo);
        }
        case kMock_GrBackend: {
            GrMockTextureInfo* mockInfo = (GrMockTextureInfo*)(handle);
            return GrBackendTexture(width, height, config, mipMapped, *mockInfo);
        }
        default:
            return GrBackendTexture();
    }
}

}  // namespace GrTest

bool GrSurfaceProxy::isWrapped_ForTesting() const {
    return SkToBool(fTarget);
}

bool GrRenderTargetContext::isWrapped_ForTesting() const {
    return fRenderTargetProxy->isWrapped_ForTesting();
}

void GrContext::setTextBlobCacheLimit_ForTesting(size_t bytes) {
    fTextBlobCache->setBudget(bytes);
}

void GrContext::setTextContextAtlasSizes_ForTesting(const GrDrawOpAtlasConfig* configs) {
    fAtlasGlyphCache->setAtlasSizes_ForTesting(configs);
}

///////////////////////////////////////////////////////////////////////////////

void GrContext::purgeAllUnlockedResources() {
    fResourceCache->purgeAllUnlocked();
}

void GrContext::resetGpuStats() const {
#if GR_GPU_STATS
    fGpu->stats()->reset();
#endif
}

void GrContext::dumpCacheStats(SkString* out) const {
#if GR_CACHE_STATS
    fResourceCache->dumpStats(out);
#endif
}

void GrContext::dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys,
                                            SkTArray<double>* values) const {
#if GR_CACHE_STATS
    fResourceCache->dumpStatsKeyValuePairs(keys, values);
#endif
}

void GrContext::printCacheStats() const {
    SkString out;
    this->dumpCacheStats(&out);
    SkDebugf("%s", out.c_str());
}

void GrContext::dumpGpuStats(SkString* out) const {
#if GR_GPU_STATS
    return fGpu->stats()->dump(out);
#endif
}

void GrContext::dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys,
                                          SkTArray<double>* values) const {
#if GR_GPU_STATS
    return fGpu->stats()->dumpKeyValuePairs(keys, values);
#endif
}

void GrContext::printGpuStats() const {
    SkString out;
    this->dumpGpuStats(&out);
    SkDebugf("%s", out.c_str());
}

sk_sp<SkImage> GrContext::getFontAtlasImage_ForTesting(GrMaskFormat format, uint32_t index) {
    GrAtlasGlyphCache* cache = this->contextPriv().getAtlasGlyphCache();

    const sk_sp<GrTextureProxy>* proxies = cache->getProxies(format);
    if (index >= cache->getAtlasPageCount(format) || !proxies[index]) {
        return nullptr;
    }

    SkASSERT(proxies[index]->priv().isExact());
    sk_sp<SkImage> image(new SkImage_Gpu(this, kNeedNewImageUniqueID, kPremul_SkAlphaType,
                                         std::move(proxies[index]), nullptr, SkBudgeted::kNo));
    return image;
}

#if GR_GPU_STATS
void GrGpu::Stats::dump(SkString* out) {
    out->appendf("Render Target Binds: %d\n", fRenderTargetBinds);
    out->appendf("Shader Compilations: %d\n", fShaderCompilations);
    out->appendf("Textures Created: %d\n", fTextureCreates);
    out->appendf("Texture Uploads: %d\n", fTextureUploads);
    out->appendf("Transfers to Texture: %d\n", fTransfersToTexture);
    out->appendf("Stencil Buffer Creates: %d\n", fStencilAttachmentCreates);
    out->appendf("Number of draws: %d\n", fNumDraws);
}

void GrGpu::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) {
    keys->push_back(SkString("render_target_binds")); values->push_back(fRenderTargetBinds);
    keys->push_back(SkString("shader_compilations")); values->push_back(fShaderCompilations);
    keys->push_back(SkString("texture_uploads")); values->push_back(fTextureUploads);
    keys->push_back(SkString("number_of_draws")); values->push_back(fNumDraws);
    keys->push_back(SkString("number_of_failed_draws")); values->push_back(fNumFailedDraws);
}

#endif

#if GR_CACHE_STATS
void GrResourceCache::getStats(Stats* stats) const {
    stats->reset();

    stats->fTotal = this->getResourceCount();
    stats->fNumNonPurgeable = fNonpurgeableResources.count();
    stats->fNumPurgeable = fPurgeableQueue.count();

    for (int i = 0; i < fNonpurgeableResources.count(); ++i) {
        stats->update(fNonpurgeableResources[i]);
    }
    for (int i = 0; i < fPurgeableQueue.count(); ++i) {
        stats->update(fPurgeableQueue.at(i));
    }
}

void GrResourceCache::dumpStats(SkString* out) const {
    this->validate();

    Stats stats;

    this->getStats(&stats);

    float countUtilization = (100.f * fBudgetedCount) / fMaxCount;
    float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes;

    out->appendf("Budget: %d items %d bytes\n", fMaxCount, (int)fMaxBytes);
    out->appendf("\t\tEntry Count: current %d"
                 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), high %d\n",
                 stats.fTotal, fBudgetedCount, stats.fWrapped, stats.fNumNonPurgeable,
                 stats.fScratch, countUtilization, fHighWaterCount);
    out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n",
                 SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization,
                 SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes));
}

void GrResourceCache::dumpStatsKeyValuePairs(SkTArray<SkString>* keys,
                                             SkTArray<double>* values) const {
    this->validate();

    Stats stats;
    this->getStats(&stats);

    keys->push_back(SkString("gpu_cache_purgable_entries")); values->push_back(stats.fNumPurgeable);
}

#endif

///////////////////////////////////////////////////////////////////////////////

void GrResourceCache::changeTimestamp(uint32_t newTimestamp) { fTimestamp = newTimestamp; }

#ifdef SK_DEBUG
int GrResourceCache::countUniqueKeysWithTag(const char* tag) const {
    int count = 0;
    UniqueHash::ConstIter iter(&fUniqueHash);
    while (!iter.done()) {
        if (0 == strcmp(tag, (*iter).getUniqueKey().tag())) {
            ++count;
        }
        ++iter;
    }
    return count;
}
#endif

///////////////////////////////////////////////////////////////////////////////

#define ASSERT_SINGLE_OWNER \
    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->singleOwner());)

uint32_t GrRenderTargetContextPriv::testingOnly_getOpListID() {
    return fRenderTargetContext->getOpList()->uniqueID();
}

uint32_t GrRenderTargetContextPriv::testingOnly_addDrawOp(std::unique_ptr<GrDrawOp> op) {
    return this->testingOnly_addDrawOp(GrNoClip(), std::move(op));
}

uint32_t GrRenderTargetContextPriv::testingOnly_addDrawOp(const GrClip& clip,
                                                          std::unique_ptr<GrDrawOp> op) {
    ASSERT_SINGLE_OWNER
    if (fRenderTargetContext->drawingManager()->wasAbandoned()) {
        return SK_InvalidUniqueID;
    }
    SkDEBUGCODE(fRenderTargetContext->validate());
    GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
                              "GrRenderTargetContext::testingOnly_addDrawOp");
    return fRenderTargetContext->addDrawOp(clip, std::move(op));
}

#undef ASSERT_SINGLE_OWNER

///////////////////////////////////////////////////////////////////////////////

GrRenderTargetFlags GrRenderTargetProxy::testingOnly_getFlags() const {
    return fRenderTargetFlags;
}

//////////////////////////////////////////////////////////////////////////////

void GrContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
    fContext->flush();
    fContext->fDrawingManager->testingOnly_removeOnFlushCallbackObject(cb);
}

void GrDrawingManager::testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
    int n = std::find(fOnFlushCBObjects.begin(), fOnFlushCBObjects.end(), cb) -
            fOnFlushCBObjects.begin();
    SkASSERT(n < fOnFlushCBObjects.count());
    fOnFlushCBObjects.removeShuffle(n);
}

//////////////////////////////////////////////////////////////////////////////

#define DRAW_OP_TEST_EXTERN(Op) \
    extern std::unique_ptr<GrDrawOp> Op##__Test(GrPaint&&, SkRandom*, GrContext*, GrFSAAType)
#define DRAW_OP_TEST_ENTRY(Op) Op##__Test

DRAW_OP_TEST_EXTERN(AAConvexPathOp);
DRAW_OP_TEST_EXTERN(AAFillRectOp);
DRAW_OP_TEST_EXTERN(AAFlatteningConvexPathOp);
DRAW_OP_TEST_EXTERN(AAHairlineOp);
DRAW_OP_TEST_EXTERN(AAStrokeRectOp);
DRAW_OP_TEST_EXTERN(CircleOp);
DRAW_OP_TEST_EXTERN(DashOp);
DRAW_OP_TEST_EXTERN(DefaultPathOp);
DRAW_OP_TEST_EXTERN(DIEllipseOp);
DRAW_OP_TEST_EXTERN(EllipseOp);
DRAW_OP_TEST_EXTERN(GrAtlasTextOp);
DRAW_OP_TEST_EXTERN(GrDrawAtlasOp);
DRAW_OP_TEST_EXTERN(GrDrawVerticesOp);
DRAW_OP_TEST_EXTERN(NonAAFillRectOp);
DRAW_OP_TEST_EXTERN(NonAALatticeOp);
DRAW_OP_TEST_EXTERN(NonAAStrokeRectOp);
DRAW_OP_TEST_EXTERN(ShadowRRectOp);
DRAW_OP_TEST_EXTERN(SmallPathOp);
DRAW_OP_TEST_EXTERN(RegionOp);
DRAW_OP_TEST_EXTERN(RRectOp);
DRAW_OP_TEST_EXTERN(TesselatingPathOp);
DRAW_OP_TEST_EXTERN(TextureOp);

void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext, GrPaint&& paint) {
    GrContext* context = renderTargetContext->surfPriv().getContext();
    using MakeDrawOpFn = std::unique_ptr<GrDrawOp>(GrPaint&&, SkRandom*, GrContext*, GrFSAAType);
    static constexpr MakeDrawOpFn* gFactories[] = {
            DRAW_OP_TEST_ENTRY(AAConvexPathOp),
            DRAW_OP_TEST_ENTRY(AAFillRectOp),
            DRAW_OP_TEST_ENTRY(AAFlatteningConvexPathOp),
            DRAW_OP_TEST_ENTRY(AAHairlineOp),
            DRAW_OP_TEST_ENTRY(AAStrokeRectOp),
            DRAW_OP_TEST_ENTRY(CircleOp),
            DRAW_OP_TEST_ENTRY(DashOp),
            DRAW_OP_TEST_ENTRY(DefaultPathOp),
            DRAW_OP_TEST_ENTRY(DIEllipseOp),
            DRAW_OP_TEST_ENTRY(EllipseOp),
            DRAW_OP_TEST_ENTRY(GrAtlasTextOp),
            DRAW_OP_TEST_ENTRY(GrDrawAtlasOp),
            DRAW_OP_TEST_ENTRY(GrDrawVerticesOp),
            DRAW_OP_TEST_ENTRY(NonAAFillRectOp),
            DRAW_OP_TEST_ENTRY(NonAALatticeOp),
            DRAW_OP_TEST_ENTRY(NonAAStrokeRectOp),
            DRAW_OP_TEST_ENTRY(ShadowRRectOp),
            DRAW_OP_TEST_ENTRY(SmallPathOp),
            DRAW_OP_TEST_ENTRY(RegionOp),
            DRAW_OP_TEST_ENTRY(RRectOp),
            DRAW_OP_TEST_ENTRY(TesselatingPathOp),
            DRAW_OP_TEST_ENTRY(TextureOp),
    };

    static constexpr size_t kTotal = SK_ARRAY_COUNT(gFactories);
    uint32_t index = random->nextULessThan(static_cast<uint32_t>(kTotal));
    auto op = gFactories[index](
            std::move(paint), random, context, renderTargetContext->fsaaType());
    SkASSERT(op);
    renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
}
<commit_msg>rm spurious std::move from getFontAtlasImage_ForTesting<commit_after>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrTest.h"
#include <algorithm>
#include "GrBackendSurface.h"
#include "GrContextOptions.h"
#include "GrContextPriv.h"
#include "GrDrawOpAtlas.h"
#include "GrDrawingManager.h"
#include "GrGpu.h"
#include "GrGpuResourceCacheAccess.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
#include "GrRenderTargetProxy.h"
#include "GrResourceCache.h"
#include "GrSemaphore.h"
#include "GrSurfaceContextPriv.h"
#include "GrTexture.h"
#include "SkGr.h"
#include "SkImage_Gpu.h"
#include "SkMathPriv.h"
#include "SkString.h"
#include "ops/GrMeshDrawOp.h"
#include "text/GrAtlasGlyphCache.h"
#include "text/GrTextBlobCache.h"

namespace GrTest {

void SetupAlwaysEvictAtlas(GrContext* context) {
    // These sizes were selected because they allow each atlas to hold a single plot and will thus
    // stress the atlas
    int dim = GrDrawOpAtlas::kGlyphMaxDim;
    GrDrawOpAtlasConfig configs[3];
    configs[kA8_GrMaskFormat].fWidth = dim;
    configs[kA8_GrMaskFormat].fHeight = dim;
    configs[kA8_GrMaskFormat].fPlotWidth = dim;
    configs[kA8_GrMaskFormat].fPlotHeight = dim;

    configs[kA565_GrMaskFormat].fWidth = dim;
    configs[kA565_GrMaskFormat].fHeight = dim;
    configs[kA565_GrMaskFormat].fPlotWidth = dim;
    configs[kA565_GrMaskFormat].fPlotHeight = dim;

    configs[kARGB_GrMaskFormat].fWidth = dim;
    configs[kARGB_GrMaskFormat].fHeight = dim;
    configs[kARGB_GrMaskFormat].fPlotWidth = dim;
    configs[kARGB_GrMaskFormat].fPlotHeight = dim;

    context->setTextContextAtlasSizes_ForTesting(configs);
}

GrBackendTexture CreateBackendTexture(GrBackend backend, int width, int height,
                                      GrPixelConfig config, GrMipMapped mipMapped,
                                      GrBackendObject handle) {
    switch (backend) {
#ifdef SK_VULKAN
        case kVulkan_GrBackend: {
            GrVkImageInfo* vkInfo = (GrVkImageInfo*)(handle);
            SkASSERT((GrMipMapped::kYes == mipMapped) == (vkInfo->fLevelCount > 1));
            return GrBackendTexture(width, height, *vkInfo);
        }
#endif
        case kOpenGL_GrBackend: {
            GrGLTextureInfo* glInfo = (GrGLTextureInfo*)(handle);
            SkASSERT(glInfo->fFormat);
            return GrBackendTexture(width, height, mipMapped, *glInfo);
        }
        case kMock_GrBackend: {
            GrMockTextureInfo* mockInfo = (GrMockTextureInfo*)(handle);
            return GrBackendTexture(width, height, config, mipMapped, *mockInfo);
        }
        default:
            return GrBackendTexture();
    }
}

}  // namespace GrTest

bool GrSurfaceProxy::isWrapped_ForTesting() const {
    return SkToBool(fTarget);
}

bool GrRenderTargetContext::isWrapped_ForTesting() const {
    return fRenderTargetProxy->isWrapped_ForTesting();
}

void GrContext::setTextBlobCacheLimit_ForTesting(size_t bytes) {
    fTextBlobCache->setBudget(bytes);
}

void GrContext::setTextContextAtlasSizes_ForTesting(const GrDrawOpAtlasConfig* configs) {
    fAtlasGlyphCache->setAtlasSizes_ForTesting(configs);
}

///////////////////////////////////////////////////////////////////////////////

void GrContext::purgeAllUnlockedResources() {
    fResourceCache->purgeAllUnlocked();
}

void GrContext::resetGpuStats() const {
#if GR_GPU_STATS
    fGpu->stats()->reset();
#endif
}

void GrContext::dumpCacheStats(SkString* out) const {
#if GR_CACHE_STATS
    fResourceCache->dumpStats(out);
#endif
}

void GrContext::dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys,
                                            SkTArray<double>* values) const {
#if GR_CACHE_STATS
    fResourceCache->dumpStatsKeyValuePairs(keys, values);
#endif
}

void GrContext::printCacheStats() const {
    SkString out;
    this->dumpCacheStats(&out);
    SkDebugf("%s", out.c_str());
}

void GrContext::dumpGpuStats(SkString* out) const {
#if GR_GPU_STATS
    return fGpu->stats()->dump(out);
#endif
}

void GrContext::dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys,
                                          SkTArray<double>* values) const {
#if GR_GPU_STATS
    return fGpu->stats()->dumpKeyValuePairs(keys, values);
#endif
}

void GrContext::printGpuStats() const {
    SkString out;
    this->dumpGpuStats(&out);
    SkDebugf("%s", out.c_str());
}

sk_sp<SkImage> GrContext::getFontAtlasImage_ForTesting(GrMaskFormat format, uint32_t index) {
    GrAtlasGlyphCache* cache = this->contextPriv().getAtlasGlyphCache();

    const sk_sp<GrTextureProxy>* proxies = cache->getProxies(format);
    if (index >= cache->getAtlasPageCount(format) || !proxies[index]) {
        return nullptr;
    }

    SkASSERT(proxies[index]->priv().isExact());
    sk_sp<SkImage> image(new SkImage_Gpu(this, kNeedNewImageUniqueID, kPremul_SkAlphaType,
                                         proxies[index], nullptr, SkBudgeted::kNo));
    return image;
}

#if GR_GPU_STATS
void GrGpu::Stats::dump(SkString* out) {
    out->appendf("Render Target Binds: %d\n", fRenderTargetBinds);
    out->appendf("Shader Compilations: %d\n", fShaderCompilations);
    out->appendf("Textures Created: %d\n", fTextureCreates);
    out->appendf("Texture Uploads: %d\n", fTextureUploads);
    out->appendf("Transfers to Texture: %d\n", fTransfersToTexture);
    out->appendf("Stencil Buffer Creates: %d\n", fStencilAttachmentCreates);
    out->appendf("Number of draws: %d\n", fNumDraws);
}

void GrGpu::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) {
    keys->push_back(SkString("render_target_binds")); values->push_back(fRenderTargetBinds);
    keys->push_back(SkString("shader_compilations")); values->push_back(fShaderCompilations);
    keys->push_back(SkString("texture_uploads")); values->push_back(fTextureUploads);
    keys->push_back(SkString("number_of_draws")); values->push_back(fNumDraws);
    keys->push_back(SkString("number_of_failed_draws")); values->push_back(fNumFailedDraws);
}

#endif

#if GR_CACHE_STATS
void GrResourceCache::getStats(Stats* stats) const {
    stats->reset();

    stats->fTotal = this->getResourceCount();
    stats->fNumNonPurgeable = fNonpurgeableResources.count();
    stats->fNumPurgeable = fPurgeableQueue.count();

    for (int i = 0; i < fNonpurgeableResources.count(); ++i) {
        stats->update(fNonpurgeableResources[i]);
    }
    for (int i = 0; i < fPurgeableQueue.count(); ++i) {
        stats->update(fPurgeableQueue.at(i));
    }
}

void GrResourceCache::dumpStats(SkString* out) const {
    this->validate();

    Stats stats;

    this->getStats(&stats);

    float countUtilization = (100.f * fBudgetedCount) / fMaxCount;
    float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes;

    out->appendf("Budget: %d items %d bytes\n", fMaxCount, (int)fMaxBytes);
    out->appendf("\t\tEntry Count: current %d"
                 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), high %d\n",
                 stats.fTotal, fBudgetedCount, stats.fWrapped, stats.fNumNonPurgeable,
                 stats.fScratch, countUtilization, fHighWaterCount);
    out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n",
                 SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization,
                 SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes));
}

void GrResourceCache::dumpStatsKeyValuePairs(SkTArray<SkString>* keys,
                                             SkTArray<double>* values) const {
    this->validate();

    Stats stats;
    this->getStats(&stats);

    keys->push_back(SkString("gpu_cache_purgable_entries")); values->push_back(stats.fNumPurgeable);
}

#endif

///////////////////////////////////////////////////////////////////////////////

void GrResourceCache::changeTimestamp(uint32_t newTimestamp) { fTimestamp = newTimestamp; }

#ifdef SK_DEBUG
int GrResourceCache::countUniqueKeysWithTag(const char* tag) const {
    int count = 0;
    UniqueHash::ConstIter iter(&fUniqueHash);
    while (!iter.done()) {
        if (0 == strcmp(tag, (*iter).getUniqueKey().tag())) {
            ++count;
        }
        ++iter;
    }
    return count;
}
#endif

///////////////////////////////////////////////////////////////////////////////

#define ASSERT_SINGLE_OWNER \
    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->singleOwner());)

uint32_t GrRenderTargetContextPriv::testingOnly_getOpListID() {
    return fRenderTargetContext->getOpList()->uniqueID();
}

uint32_t GrRenderTargetContextPriv::testingOnly_addDrawOp(std::unique_ptr<GrDrawOp> op) {
    return this->testingOnly_addDrawOp(GrNoClip(), std::move(op));
}

uint32_t GrRenderTargetContextPriv::testingOnly_addDrawOp(const GrClip& clip,
                                                          std::unique_ptr<GrDrawOp> op) {
    ASSERT_SINGLE_OWNER
    if (fRenderTargetContext->drawingManager()->wasAbandoned()) {
        return SK_InvalidUniqueID;
    }
    SkDEBUGCODE(fRenderTargetContext->validate());
    GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
                              "GrRenderTargetContext::testingOnly_addDrawOp");
    return fRenderTargetContext->addDrawOp(clip, std::move(op));
}

#undef ASSERT_SINGLE_OWNER

///////////////////////////////////////////////////////////////////////////////

GrRenderTargetFlags GrRenderTargetProxy::testingOnly_getFlags() const {
    return fRenderTargetFlags;
}

//////////////////////////////////////////////////////////////////////////////

void GrContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
    fContext->flush();
    fContext->fDrawingManager->testingOnly_removeOnFlushCallbackObject(cb);
}

void GrDrawingManager::testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
    int n = std::find(fOnFlushCBObjects.begin(), fOnFlushCBObjects.end(), cb) -
            fOnFlushCBObjects.begin();
    SkASSERT(n < fOnFlushCBObjects.count());
    fOnFlushCBObjects.removeShuffle(n);
}

//////////////////////////////////////////////////////////////////////////////

#define DRAW_OP_TEST_EXTERN(Op) \
    extern std::unique_ptr<GrDrawOp> Op##__Test(GrPaint&&, SkRandom*, GrContext*, GrFSAAType)
#define DRAW_OP_TEST_ENTRY(Op) Op##__Test

DRAW_OP_TEST_EXTERN(AAConvexPathOp);
DRAW_OP_TEST_EXTERN(AAFillRectOp);
DRAW_OP_TEST_EXTERN(AAFlatteningConvexPathOp);
DRAW_OP_TEST_EXTERN(AAHairlineOp);
DRAW_OP_TEST_EXTERN(AAStrokeRectOp);
DRAW_OP_TEST_EXTERN(CircleOp);
DRAW_OP_TEST_EXTERN(DashOp);
DRAW_OP_TEST_EXTERN(DefaultPathOp);
DRAW_OP_TEST_EXTERN(DIEllipseOp);
DRAW_OP_TEST_EXTERN(EllipseOp);
DRAW_OP_TEST_EXTERN(GrAtlasTextOp);
DRAW_OP_TEST_EXTERN(GrDrawAtlasOp);
DRAW_OP_TEST_EXTERN(GrDrawVerticesOp);
DRAW_OP_TEST_EXTERN(NonAAFillRectOp);
DRAW_OP_TEST_EXTERN(NonAALatticeOp);
DRAW_OP_TEST_EXTERN(NonAAStrokeRectOp);
DRAW_OP_TEST_EXTERN(ShadowRRectOp);
DRAW_OP_TEST_EXTERN(SmallPathOp);
DRAW_OP_TEST_EXTERN(RegionOp);
DRAW_OP_TEST_EXTERN(RRectOp);
DRAW_OP_TEST_EXTERN(TesselatingPathOp);
DRAW_OP_TEST_EXTERN(TextureOp);

void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext, GrPaint&& paint) {
    GrContext* context = renderTargetContext->surfPriv().getContext();
    using MakeDrawOpFn = std::unique_ptr<GrDrawOp>(GrPaint&&, SkRandom*, GrContext*, GrFSAAType);
    static constexpr MakeDrawOpFn* gFactories[] = {
            DRAW_OP_TEST_ENTRY(AAConvexPathOp),
            DRAW_OP_TEST_ENTRY(AAFillRectOp),
            DRAW_OP_TEST_ENTRY(AAFlatteningConvexPathOp),
            DRAW_OP_TEST_ENTRY(AAHairlineOp),
            DRAW_OP_TEST_ENTRY(AAStrokeRectOp),
            DRAW_OP_TEST_ENTRY(CircleOp),
            DRAW_OP_TEST_ENTRY(DashOp),
            DRAW_OP_TEST_ENTRY(DefaultPathOp),
            DRAW_OP_TEST_ENTRY(DIEllipseOp),
            DRAW_OP_TEST_ENTRY(EllipseOp),
            DRAW_OP_TEST_ENTRY(GrAtlasTextOp),
            DRAW_OP_TEST_ENTRY(GrDrawAtlasOp),
            DRAW_OP_TEST_ENTRY(GrDrawVerticesOp),
            DRAW_OP_TEST_ENTRY(NonAAFillRectOp),
            DRAW_OP_TEST_ENTRY(NonAALatticeOp),
            DRAW_OP_TEST_ENTRY(NonAAStrokeRectOp),
            DRAW_OP_TEST_ENTRY(ShadowRRectOp),
            DRAW_OP_TEST_ENTRY(SmallPathOp),
            DRAW_OP_TEST_ENTRY(RegionOp),
            DRAW_OP_TEST_ENTRY(RRectOp),
            DRAW_OP_TEST_ENTRY(TesselatingPathOp),
            DRAW_OP_TEST_ENTRY(TextureOp),
    };

    static constexpr size_t kTotal = SK_ARRAY_COUNT(gFactories);
    uint32_t index = random->nextULessThan(static_cast<uint32_t>(kTotal));
    auto op = gFactories[index](
            std::move(paint), random, context, renderTargetContext->fsaaType());
    SkASSERT(op);
    renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
}
<|endoftext|>


<commit_before>#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/export.hpp>

#include <fstream>
#include <iostream>
#include <sstream>
#define CV 1

#include "caosVar.h"
#include "ser/caosVar.h"
#include "caosScript.h"
#include "ser/caosScript.h"

class foo {
    public:
        int i;
        foo() : i(0) {}
        foo(int j) : i(j) {}
    private:
        friend class boost::serialization::access;

        template<class Archive>
            void serialize(Archive &ar, const unsigned int version) {
                ar & BOOST_SERIALIZATION_NVP(i);
            }
};

int main(void) {

    registerDelegates();

    std::ofstream ofs("sertest.dat");
    caosVar null, str, intv, floatv;
    caosScript scr("c3", "<test input>");

    null.reset();
    str.setString("Hello, world!");
    intv.setInt(42);
    floatv.setFloat(0.5);

    std::istringstream ss("inst sets va00 \"hello world\\n\" outv 42 outs \"\\n\" outs va00 slow stop rscr");
    scr.parse(ss);

    {
        const foo v(42);
        boost::archive::text_oarchive oa(ofs);
        oa << v;
        oa << (const caosVar &)null << (const caosVar &)str << (const caosVar &)intv << (const caosVar &)floatv;
        oa << (const caosScript &)scr;
    }
    ofs.close();

    caosVar nnull, nstr, nintv, nfloatv;
    caosScript si;
    {
        foo v;
        std::ifstream ifs("sertest.dat", std::ios::binary);
        boost::archive::text_iarchive ia(ifs);
        ia >> v;
        std::cout << "v.i = " << v.i << std::endl;
        ia >> nnull >> nstr >> nintv >> nfloatv;
        ia >> si;
    }

#if CV
#define D(x) std::cout << #x << " = " << x.dump() << std::endl
#else
#define D(x) do { } while (0)
#endif
    D(nnull); D(nstr); D(nintv); D(nfloatv);
    std::cout << si.installer->dump() << std::endl;
    return 0;
}
<commit_msg>tools/serialtest: accept COS file on command line<commit_after>#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/export.hpp>

#include <fstream>
#include <iostream>
#include <sstream>
#define CV 1

#include "caosVar.h"
#include "ser/caosVar.h"
#include "caosScript.h"
#include "ser/caosScript.h"

class foo {
    public:
        int i;
        foo() : i(0) {}
        foo(int j) : i(j) {}
    private:
        friend class boost::serialization::access;

        template<class Archive>
            void serialize(Archive &ar, const unsigned int version) {
                ar & BOOST_SERIALIZATION_NVP(i);
            }
};

int main(int argc, char **argv) {

    registerDelegates();

    std::ofstream ofs("sertest.dat");
    caosVar null, str, intv, floatv;
    caosScript scr("c3", "<test input>");

    null.reset();
    str.setString("Hello, world!");
    intv.setInt(42);
    floatv.setFloat(0.5);

    std::istringstream ss("inst sets va00 \"hello world\\n\" outv 42 outs \"\\n\" outs va00 slow stop rscr");

    if (argc != 2)
        scr.parse(ss);
    else {
        std::ifstream ifs(argv[1]);
        scr.parse(ifs);
    }

    {
        const foo v(42);
        boost::archive::text_oarchive oa(ofs);
        oa << v;
        oa << (const caosVar &)null << (const caosVar &)str << (const caosVar &)intv << (const caosVar &)floatv;
        oa << (const caosScript &)scr;
    }
    ofs.close();

    caosVar nnull, nstr, nintv, nfloatv;
    caosScript si;
    {
        foo v;
        std::ifstream ifs("sertest.dat", std::ios::binary);
        boost::archive::text_iarchive ia(ifs);
        ia >> v;
        std::cout << "v.i = " << v.i << std::endl;
        ia >> nnull >> nstr >> nintv >> nfloatv;
        ia >> si;
    }

#if CV
#define D(x) std::cout << #x << " = " << x.dump() << std::endl
#else
#define D(x) do { } while (0)
#endif
    D(nnull); D(nstr); D(nintv); D(nfloatv);
    std::cout << si.installer->dump() << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
Authors:
Michael Berg <michael.berg@zalf.de>

Maintainers:
Currently maintained by the authors.

This file is part of the util library used by models created at the Institute of
Landscape Systems Analysis at the ZALF.
Copyright (C) Leibniz Centre for Agricultural Landscape Research (ZALF)
*/

#include <sstream>

#include "zmq-helper.h"

using namespace Tools;
using namespace std;
using namespace json11;

#ifndef NO_ZMQ
Msg Tools::receiveMsg(zmq::socket_t& socket, int topicCharCount, bool nonBlockingMode)
{
  zmq::message_t message;
  if(socket.recv(&message, nonBlockingMode ? ZMQ_NOBLOCK : 0))
  {
    std::string strMsg(static_cast<char*>(message.data()), message.size());
		std::string topic = topicCharCount > 0 ? strMsg.substr(0, topicCharCount) : "";
		strMsg = strMsg.substr(topicCharCount);

    //cout << "receiveMsg: " << strMsg << endl;

    //    string strMsg = s_recv(pullSocket);
    string err;
    const Json& jsonMsg = Json::parse(strMsg, err);
    return Msg{jsonMsg, err, topic, (err.empty() ? "" : strMsg), true};
  }
  return Msg{Json(), "", "", false};
}
#endif

<commit_msg>fixed constructor call<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
Authors:
Michael Berg <michael.berg@zalf.de>

Maintainers:
Currently maintained by the authors.

This file is part of the util library used by models created at the Institute of
Landscape Systems Analysis at the ZALF.
Copyright (C) Leibniz Centre for Agricultural Landscape Research (ZALF)
*/

#include <sstream>

#include "zmq-helper.h"

using namespace Tools;
using namespace std;
using namespace json11;

#ifndef NO_ZMQ
Msg Tools::receiveMsg(zmq::socket_t& socket, int topicCharCount, bool nonBlockingMode)
{
  zmq::message_t message;
  if(socket.recv(&message, nonBlockingMode ? ZMQ_NOBLOCK : 0))
  {
    std::string strMsg(static_cast<char*>(message.data()), message.size());
		std::string topic = topicCharCount > 0 ? strMsg.substr(0, topicCharCount) : "";
		strMsg = strMsg.substr(topicCharCount);

    //cout << "receiveMsg: " << strMsg << endl;

    //    string strMsg = s_recv(pullSocket);
    string err;
    const Json& jsonMsg = Json::parse(strMsg, err);
    return Msg{jsonMsg, err, topic, (err.empty() ? "" : strMsg), true};
  }
  return Msg{Json(), "", "", "", false};
}
#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tbxcolor.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2004-11-26 20:13:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_TBXCOLOR_HXX
#define _SVX_TBXCOLOR_HXX

#ifndef _DRAFTS_COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_
#include <drafts/com/sun/star/frame/XLayoutManager.hpp>
#endif

//........................................................................
namespace svx
{
//........................................................................

    //====================================================================
    //= ToolboxAccess
    //====================================================================
    class ToolboxAccess
    {
    private:
        bool                                                    m_bDocking;
        ::rtl::OUString                                         m_sToolboxResName;
        ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::frame::XLayoutManager >   m_xLayouter;

    public:
        ToolboxAccess( const ::rtl::OUString& rToolboxName );

    public:
        /** toggles the toolbox
        */
        void        toggleToolbox() const;

        /** determines whether the toolbox is currently visible
        */
        bool        isToolboxVisible() const;

        /** forces that the toolbox is docked
        */
        inline void forceDocking() { m_bDocking = true; }
    };

//........................................................................
} // namespace svx
//........................................................................

#endif // #ifndef _SVX_TBXCOLOR_HXX

<commit_msg>INTEGRATION: CWS visibility01 (1.2.8); FILE MERGED 2005/01/12 07:40:11 mnicel 1.2.8.2: RESYNC: (1.2-1.3); FILE MERGED Marked up remaned ToolbocAccess 2004/11/19 12:54:33 mmeeks 1.2.8.1: Issue number: #i35758# Submitted by: mnicel Reviewed by:  mmeeks<commit_after>/*************************************************************************
 *
 *  $RCSfile: tbxcolor.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 15:38:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_TBXCOLOR_HXX
#define _SVX_TBXCOLOR_HXX

#ifndef _DRAFTS_COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_
#include <drafts/com/sun/star/frame/XLayoutManager.hpp>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

//........................................................................
namespace svx
{
//........................................................................

    //====================================================================
    //= ToolboxAccess
    //====================================================================
    class SVX_DLLPUBLIC ToolboxAccess
    {
    private:
        bool                                                    m_bDocking;
        ::rtl::OUString                                         m_sToolboxResName;
        ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::frame::XLayoutManager >   m_xLayouter;

    public:
        ToolboxAccess( const ::rtl::OUString& rToolboxName );

    public:
        /** toggles the toolbox
        */
        void        toggleToolbox() const;

        /** determines whether the toolbox is currently visible
        */
        bool        isToolboxVisible() const;

        /** forces that the toolbox is docked
        */
        inline void forceDocking() { m_bDocking = true; }
    };

//........................................................................
} // namespace svx
//........................................................................

#endif // #ifndef _SVX_TBXCOLOR_HXX

<|endoftext|>