<commit_before>// @(#)root/roostats:$Id$
// Author: Kyle Cranmer, Sven Kreiss   23/05/10
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/**
Same purpose as HybridCalculatorOriginal, but different implementation.
*/

#include "RooStats/HybridCalculator.h"
#include "RooStats/ToyMCSampler.h"

ClassImp(RooStats::HybridCalculator)

using namespace RooStats;
using namespace std;

int HybridCalculator::CheckHook(void) const {

   if( fPriorNuisanceNull && (!fNullModel->GetNuisanceParameters() || fNullModel->GetNuisanceParameters()->getSize() == 0) ) {
      oocoutE((TObject*)0,InputArguments)  << "HybridCalculator - Nuisance PDF has been specified, but is unaware of which parameters are the nuisance parameters. Must set nuisance parameters in the Null ModelConfig." << endl;
      return -1; // error
   }
   if( fPriorNuisanceAlt && (!fAltModel->GetNuisanceParameters() || fAltModel->GetNuisanceParameters()->getSize() == 0) ) {
      oocoutE((TObject*)0,InputArguments)  << "HybridCalculator - Nuisance PDF has been specified, but is unaware of which parameters are the nuisance parameters. Must set nuisance parameters in the Alt ModelConfig" << endl;
      return -1; // error
   }

   return 0; // ok
}

int HybridCalculator::PreNullHook(RooArgSet* /*parameterPoint*/, double obsTestStat) const {

   std::cout << "PreNullHook: " << fNullModel->GetNuisanceParameters() << " " << fPriorNuisanceNull << std::endl;
   if(fNullModel->GetNuisanceParameters()) fNullModel->GetNuisanceParameters()->Print();

   // ****** any TestStatSampler ********

   if(fPriorNuisanceNull) {
      // Setup Priors for ad hoc Hybrid
      fTestStatSampler->SetPriorNuisance(fPriorNuisanceNull);
   } else if(
      fNullModel->GetNuisanceParameters() == NULL ||
      fNullModel->GetNuisanceParameters()->getSize() == 0
   ) {
      oocoutI((TObject*)0,InputArguments)
       << "HybridCalculator - No nuisance parameters specified for Null model and no prior forced. "
       << "Case is reduced to simple hypothesis testing with no uncertainty." << endl;
   } else {
      oocoutI((TObject*)0,InputArguments) << "HybridCalculator - Using uniform prior on nuisance parameters (Null model)." << endl;
   }

   // ***** ToyMCSampler specific *******

   // check whether TestStatSampler is a ToyMCSampler
   ToyMCSampler *toymcs = dynamic_cast<ToyMCSampler*>(GetTestStatSampler());
   if(toymcs) {
      oocoutI((TObject*)0,InputArguments) << "Using a ToyMCSampler. Now configuring for Null." << endl;

      // variable number of toys
      if(fNToysNull >= 0) toymcs->SetNToys(fNToysNull);

      // adaptive sampling
      if(fNToysNullTail) {
         oocoutI((TObject*)0,InputArguments) << "Adaptive Sampling" << endl;
         if(GetTestStatSampler()->GetTestStatistic()->PValueIsRightTail()) {
            toymcs->SetToysRightTail(fNToysNullTail, obsTestStat);
         }else{
            toymcs->SetToysLeftTail(fNToysNullTail, obsTestStat);
         }
      }else{
         toymcs->SetToysBothTails(0, 0, obsTestStat); // disable adaptive sampling
      }

      GetNullModel()->LoadSnapshot();
   }

   return 0;
}

int HybridCalculator::PreAltHook(RooArgSet* /*parameterPoint*/, double obsTestStat) const {

   // ****** any TestStatSampler ********

   if(fPriorNuisanceAlt){
     // Setup Priors for ad hoc Hybrid
     fTestStatSampler->SetPriorNuisance(fPriorNuisanceAlt);
   } else if (
      fAltModel->GetNuisanceParameters()==NULL ||
      fAltModel->GetNuisanceParameters()->getSize()==0
   ) {
      oocoutI((TObject*)0,InputArguments)
       << "HybridCalculator - No nuisance parameters specified for Alt model and no prior forced. "
       << "Case is reduced to simple hypothesis testing with no uncertainty." << endl;
   } else {
      oocoutI((TObject*)0,InputArguments) << "HybridCalculator - Using uniform prior on nuisance parameters (Alt model)." << endl;
   }

   // ***** ToyMCSampler specific *******

   // check whether TestStatSampler is a ToyMCSampler
   ToyMCSampler *toymcs = dynamic_cast<ToyMCSampler*>(GetTestStatSampler());
   if(toymcs) {
      oocoutI((TObject*)0,InputArguments) << "Using a ToyMCSampler. Now configuring for Alt." << endl;

      // variable number of toys
      if(fNToysAlt >= 0) toymcs->SetNToys(fNToysAlt);

      // adaptive sampling
      if(fNToysAltTail) {
         oocoutI((TObject*)0,InputArguments) << "Adaptive Sampling" << endl;
         if(GetTestStatSampler()->GetTestStatistic()->PValueIsRightTail()) {
            toymcs->SetToysLeftTail(fNToysAltTail, obsTestStat);
         }else{
            toymcs->SetToysRightTail(fNToysAltTail, obsTestStat);
         }
      }else{
         toymcs->SetToysBothTails(0, 0, obsTestStat); // disable adaptive sampling
      }
   }

   return 0;
}

<commit_msg>remove a printing statement<commit_after>// @(#)root/roostats:$Id$
// Author: Kyle Cranmer, Sven Kreiss   23/05/10
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/**
Same purpose as HybridCalculatorOriginal, but different implementation.
*/

#include "RooStats/HybridCalculator.h"
#include "RooStats/ToyMCSampler.h"

ClassImp(RooStats::HybridCalculator)

using namespace RooStats;
using namespace std;

int HybridCalculator::CheckHook(void) const {

   if( fPriorNuisanceNull && (!fNullModel->GetNuisanceParameters() || fNullModel->GetNuisanceParameters()->getSize() == 0) ) {
      oocoutE((TObject*)0,InputArguments)  << "HybridCalculator - Nuisance PDF has been specified, but is unaware of which parameters are the nuisance parameters. Must set nuisance parameters in the Null ModelConfig." << endl;
      return -1; // error
   }
   if( fPriorNuisanceAlt && (!fAltModel->GetNuisanceParameters() || fAltModel->GetNuisanceParameters()->getSize() == 0) ) {
      oocoutE((TObject*)0,InputArguments)  << "HybridCalculator - Nuisance PDF has been specified, but is unaware of which parameters are the nuisance parameters. Must set nuisance parameters in the Alt ModelConfig" << endl;
      return -1; // error
   }

   return 0; // ok
}

int HybridCalculator::PreNullHook(RooArgSet* /*parameterPoint*/, double obsTestStat) const {

   // ****** any TestStatSampler ********

   if(fPriorNuisanceNull) {
      // Setup Priors for ad hoc Hybrid
      fTestStatSampler->SetPriorNuisance(fPriorNuisanceNull);
   } else if(
      fNullModel->GetNuisanceParameters() == NULL ||
      fNullModel->GetNuisanceParameters()->getSize() == 0
   ) {
      oocoutI((TObject*)0,InputArguments)
       << "HybridCalculator - No nuisance parameters specified for Null model and no prior forced. "
       << "Case is reduced to simple hypothesis testing with no uncertainty." << endl;
   } else {
      oocoutI((TObject*)0,InputArguments) << "HybridCalculator - Using uniform prior on nuisance parameters (Null model)." << endl;
   }

   // ***** ToyMCSampler specific *******

   // check whether TestStatSampler is a ToyMCSampler
   ToyMCSampler *toymcs = dynamic_cast<ToyMCSampler*>(GetTestStatSampler());
   if(toymcs) {
      oocoutI((TObject*)0,InputArguments) << "Using a ToyMCSampler. Now configuring for Null." << endl;

      // variable number of toys
      if(fNToysNull >= 0) toymcs->SetNToys(fNToysNull);

      // adaptive sampling
      if(fNToysNullTail) {
         oocoutI((TObject*)0,InputArguments) << "Adaptive Sampling" << endl;
         if(GetTestStatSampler()->GetTestStatistic()->PValueIsRightTail()) {
            toymcs->SetToysRightTail(fNToysNullTail, obsTestStat);
         }else{
            toymcs->SetToysLeftTail(fNToysNullTail, obsTestStat);
         }
      }else{
         toymcs->SetToysBothTails(0, 0, obsTestStat); // disable adaptive sampling
      }

      GetNullModel()->LoadSnapshot();
   }

   return 0;
}

int HybridCalculator::PreAltHook(RooArgSet* /*parameterPoint*/, double obsTestStat) const {

   // ****** any TestStatSampler ********

   if(fPriorNuisanceAlt){
     // Setup Priors for ad hoc Hybrid
     fTestStatSampler->SetPriorNuisance(fPriorNuisanceAlt);
   } else if (
      fAltModel->GetNuisanceParameters()==NULL ||
      fAltModel->GetNuisanceParameters()->getSize()==0
   ) {
      oocoutI((TObject*)0,InputArguments)
       << "HybridCalculator - No nuisance parameters specified for Alt model and no prior forced. "
       << "Case is reduced to simple hypothesis testing with no uncertainty." << endl;
   } else {
      oocoutI((TObject*)0,InputArguments) << "HybridCalculator - Using uniform prior on nuisance parameters (Alt model)." << endl;
   }

   // ***** ToyMCSampler specific *******

   // check whether TestStatSampler is a ToyMCSampler
   ToyMCSampler *toymcs = dynamic_cast<ToyMCSampler*>(GetTestStatSampler());
   if(toymcs) {
      oocoutI((TObject*)0,InputArguments) << "Using a ToyMCSampler. Now configuring for Alt." << endl;

      // variable number of toys
      if(fNToysAlt >= 0) toymcs->SetNToys(fNToysAlt);

      // adaptive sampling
      if(fNToysAltTail) {
         oocoutI((TObject*)0,InputArguments) << "Adaptive Sampling" << endl;
         if(GetTestStatSampler()->GetTestStatistic()->PValueIsRightTail()) {
            toymcs->SetToysLeftTail(fNToysAltTail, obsTestStat);
         }else{
            toymcs->SetToysRightTail(fNToysAltTail, obsTestStat);
         }
      }else{
         toymcs->SetToysBothTails(0, 0, obsTestStat); // disable adaptive sampling
      }
   }

   return 0;
}

<|endoftext|>


<commit_before>#include "chig/Context.hpp"
#include "chig/GraphFunction.hpp"
#include "chig/JsonModule.hpp"
#include "chig/LangModule.hpp"
#include "chig/NodeType.hpp"

#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Target/TargetOptions.h>

#include <boost/filesystem.hpp>
#include <boost/range.hpp>

#include <llvm/Target/TargetMachine.h>
#include <chig/CModule.hpp>
#include <gsl/gsl>

using namespace llvm;

namespace fs = boost::filesystem;

namespace chig {
Context::Context(const boost::filesystem::path& workPath) {
	mLLVMContext = std::make_unique<llvm::LLVMContext>();

	mWorkspacePath = workspaceFromChildPath(workPath);
}
ChigModule* Context::moduleByName(gsl::cstring_span<> moduleName) const noexcept {
	Result res;

	for (auto& module : mModules) {
		if (module->name() == moduleName) { return module.get(); }
	}
	return nullptr;
}

ChigModule* Context::moduleByFullName(gsl::cstring_span<> fullModuleName) const noexcept {
	Result res;

	for (auto& module : mModules) {
		if (module->fullName() == fullModuleName) { return module.get(); }
	}
	return nullptr;
}

JsonModule* Context::newJsonModule(gsl::cstring_span<> fullName) {
	// create the module
	JsonModule* mod = nullptr;
	{
		auto uMod =
			std::make_unique<JsonModule>(*this, gsl::to_string(fullName), gsl::span<std::string>());

		mod = uMod.get();
		addModule(std::move(uMod));
	}

	// if we have a workspace bound, then serialize
	if (hasWorkspace()) {
		Result r = mod->saveToDisk();
		Expects(r.success);  // It's default constructed, so it really shoudln't fail.
	}

	return mod;
}

std::unordered_set<std::string> Context::listModulesInWorkspace() const noexcept {
	std::unordered_set<std::string> moduleList;

	fs::path srcDir = workspacePath() / "src";

	if (!fs::is_directory(srcDir)) { return {}; }

	for (const auto& dirEntry : boost::make_iterator_range(
			 fs::recursive_directory_iterator{srcDir, fs::symlink_option::recurse}, {})) {
		const fs::path& p = dirEntry;

		// see if it's a chigraph module
		if (fs::is_regular_file(p) && p.extension() == ".chigmod") {
			fs::path relPath = fs::relative(p, srcDir);

			relPath.replace_extension("");  // remove .chigmod
			moduleList.insert(relPath.string());
		}
	}

	return moduleList;
}

chig::Result chig::Context::loadModule(const gsl::cstring_span<> name, ChigModule** toFill) {
	Result res;

	// check for built-in modules
	if (name == "lang") {
		auto mod = std::make_unique<LangModule>(*this);
		if (toFill != nullptr) { *toFill = mod.get(); }
		addModule(std::move(mod));
		return {};
	}
	if (name == "c") {
		auto mod = std::make_unique<CModule>(*this);
		if (toFill != nullptr) { *toFill = mod.get(); }
		addModule(std::move(mod));  // we don't care if it's actually added
		return {};
	}

	if (workspacePath().empty()) {
		res.addEntry("EUKN", "Cannot load module without a workspace path",
					 {{"Requested Module"}, gsl::to_string(name)});
		return res;
	}

	// find it in the workspace
	fs::path fullPath = workspacePath() / "src" / (gsl::to_string(name) + ".chigmod");

	if (!fs::is_regular_file(fullPath)) {
		res.addEntry(
			"EUKN", "Failed to find module",
			{{"Module Name", gsl::to_string(name)}, {"Workspace Path", workspacePath().string()}});
		return res;
	}

	// load the JSON
	nlohmann::json readJson = {};
	{
		fs::ifstream inFile{fullPath};

		inFile >> readJson;
	}

	JsonModule* toFillJson = nullptr;
	res += addModuleFromJson(name, readJson, &toFillJson);
	if (toFill != nullptr) { *toFill = toFillJson; }

	return res;
}

Result Context::addModuleFromJson(gsl::cstring_span<> fullName, const nlohmann::json& json,
								  JsonModule** toFill) {
	Result res;

	// make sure it's not already added
	{
		auto mod = moduleByFullName(fullName);
		if (mod != nullptr) {
			if (toFill != nullptr) {
				auto casted = dynamic_cast<JsonModule*>(mod);
				if (casted != nullptr) { *toFill = casted; }
			}
			return {};
		}
	}

	// Create the module
	JsonModule* cPtr = nullptr;
	{
		// parse module
		auto jmod = std::make_unique<JsonModule>(*this, gsl::to_string(fullName), json, &res);
		if (!res) { return res; }
		if (toFill != nullptr) { *toFill = jmod.get(); }

		cPtr	   = jmod.get();
		bool added = addModule(std::move(jmod));
		Expects(added);  // it really should be added
	}

	// load graphs
	res += cPtr->loadGraphs();

	return res;
}

bool Context::addModule(std::unique_ptr<ChigModule> modToAdd) noexcept {
	Expects(modToAdd != nullptr);

	// make sure it's unique
	auto ptr = moduleByFullName(modToAdd->fullName());
	if (ptr != nullptr) { return false; }

	mModules.push_back(std::move(modToAdd));

	Expects(modToAdd == nullptr);

	return true;
}

Result Context::typeFromModule(gsl::cstring_span<> module, gsl::cstring_span<> name,
							   DataType* toFill) noexcept {
	Expects(toFill != nullptr);

	Result res;

	ChigModule* mod = moduleByName(module);
	if (mod == nullptr) {
		res.addEntry("E36", "Could not find module", {{"module", gsl::to_string(module)}});
		return res;
	}

	*toFill = mod->typeFromName(name);
	if (!toFill->valid()) {
		res.addEntry("E37", "Could not find type in module",
					 {{"type", gsl::to_string(name)}, {"module", gsl::to_string(module)}});
	}

	return res;
}

Result Context::debugTypeFromModule(gsl::cstring_span<> module, gsl::cstring_span<> name,
									llvm::DIType** toFill) noexcept {
	Expects(toFill != nullptr);

	Result res;

	ChigModule* mod = moduleByName(module);
	if (mod == nullptr) {
		res.addEntry("E36", "Could not find module", {{"module", gsl::to_string(module)}});
		return res;
	}

	*toFill = mod->debugTypeFromName(name);
	if (*toFill == nullptr) {
		res.addEntry("E37", "Could not find type in module",
					 {{"type", gsl::to_string(name)}, {"module", gsl::to_string(module)}});
	}

	return res;
}

Result Context::nodeTypeFromModule(gsl::cstring_span<> moduleName, gsl::cstring_span<> typeName,
								   const nlohmann::json&	  data,
								   std::unique_ptr<NodeType>* toFill) noexcept {
	Result res;

	auto module = moduleByName(moduleName);
	if (module == nullptr) {
		res.addEntry("E36", "Could not find module", {{"module", gsl::to_string(moduleName)}});
		return res;
	}

	res += module->nodeTypeFromName(typeName, data, toFill);

	return res;
}

Result Context::compileModule(gsl::cstring_span<> fullName, std::unique_ptr<llvm::Module>* toFill) {
	Expects(toFill != nullptr);

	Result res;

	auto chigmod = moduleByFullName(fullName);

	if (chigmod == nullptr) {
		res.addEntry("E36", "Could not find module", {{"module", gsl::to_string(fullName)}});
		return res;
	}

	auto llmod = std::make_unique<llvm::Module>(gsl::to_string(fullName), llvmContext());

	// generate dependencies
	for (const auto& depName : chigmod->dependencies()) {
		std::unique_ptr<llvm::Module> compiledDep;
		res += compileModule(depName, &compiledDep);  // TODO: detect circular dependencies

		if (!res) { return res; }

		// link it in
#if LLVM_VERSION_MAJOR <= 3 && LLVM_VERSION_MINOR <= 7
        llvm::Linker::LinkModules(llmod, compiledDep.get());
#else
		llvm::Linker::linkModules(*llmod, std::move(compiledDep));
#endif
	}

	res += chigmod->generateModule(*llmod);

	// set debug info version if it doesn't already have it
	if (llmod->getModuleFlag("Debug Info Version") == nullptr) {
		llmod->addModuleFlag(llvm::Module::Warning, "Debug Info Version",
							 llvm::DEBUG_METADATA_VERSION);
	}

	// verify the created module
	if (res) {
		std::string				 err;
		llvm::raw_string_ostream os(err);
		if (llvm::verifyModule(*llmod, &os)) {
			std::string moduleStr;
			{
				llvm::raw_string_ostream printerStr{moduleStr};
				llmod->print(printerStr, nullptr);
			}
			res.addEntry(
				"EINT", "Internal compiler error: Invalid module created",
				{{"Error", err}, {"Full Name", gsl::to_string(fullName)}, {"Module", moduleStr}});
		}
	}

	*toFill = std::move(llmod);

	return res;
}

std::string Context::fullModuleName(gsl::cstring_span<> shortName) const {
	auto mod = moduleByName(shortName);

	if (mod != nullptr) { return mod->fullName(); }

	return "";
}
fs::path workspaceFromChildPath(const fs::path& path) {
	fs::path ret = path;

	// initialize workspace directory
	// go up until it is a workspace
	while (!ret.empty() && !fs::is_regular_file(ret / ".chigraphworkspace")) {
		ret = ret.parent_path();
	}

	return ret;  // it's ok if it's empty
}

std::string stringifyLLVMType(llvm::Type* ty) {
	Expects(ty != nullptr);

	std::string data;
	{
		llvm::raw_string_ostream stream{data};
		ty->print(stream);
	}
	return data;
}

}  // namespace chig
<commit_msg>Fix syntax error<commit_after>#include "chig/Context.hpp"
#include "chig/GraphFunction.hpp"
#include "chig/JsonModule.hpp"
#include "chig/LangModule.hpp"
#include "chig/NodeType.hpp"

#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Target/TargetOptions.h>

#include <boost/filesystem.hpp>
#include <boost/range.hpp>

#include <llvm/Target/TargetMachine.h>
#include <chig/CModule.hpp>
#include <gsl/gsl>

using namespace llvm;

namespace fs = boost::filesystem;

namespace chig {
Context::Context(const boost::filesystem::path& workPath) {
	mLLVMContext = std::make_unique<llvm::LLVMContext>();

	mWorkspacePath = workspaceFromChildPath(workPath);
}
ChigModule* Context::moduleByName(gsl::cstring_span<> moduleName) const noexcept {
	Result res;

	for (auto& module : mModules) {
		if (module->name() == moduleName) { return module.get(); }
	}
	return nullptr;
}

ChigModule* Context::moduleByFullName(gsl::cstring_span<> fullModuleName) const noexcept {
	Result res;

	for (auto& module : mModules) {
		if (module->fullName() == fullModuleName) { return module.get(); }
	}
	return nullptr;
}

JsonModule* Context::newJsonModule(gsl::cstring_span<> fullName) {
	// create the module
	JsonModule* mod = nullptr;
	{
		auto uMod =
			std::make_unique<JsonModule>(*this, gsl::to_string(fullName), gsl::span<std::string>());

		mod = uMod.get();
		addModule(std::move(uMod));
	}

	// if we have a workspace bound, then serialize
	if (hasWorkspace()) {
		Result r = mod->saveToDisk();
		Expects(r.success);  // It's default constructed, so it really shoudln't fail.
	}

	return mod;
}

std::unordered_set<std::string> Context::listModulesInWorkspace() const noexcept {
	std::unordered_set<std::string> moduleList;

	fs::path srcDir = workspacePath() / "src";

	if (!fs::is_directory(srcDir)) { return {}; }

	for (const auto& dirEntry : boost::make_iterator_range(
			 fs::recursive_directory_iterator{srcDir, fs::symlink_option::recurse}, {})) {
		const fs::path& p = dirEntry;

		// see if it's a chigraph module
		if (fs::is_regular_file(p) && p.extension() == ".chigmod") {
			fs::path relPath = fs::relative(p, srcDir);

			relPath.replace_extension("");  // remove .chigmod
			moduleList.insert(relPath.string());
		}
	}

	return moduleList;
}

chig::Result chig::Context::loadModule(const gsl::cstring_span<> name, ChigModule** toFill) {
	Result res;

	// check for built-in modules
	if (name == "lang") {
		auto mod = std::make_unique<LangModule>(*this);
		if (toFill != nullptr) { *toFill = mod.get(); }
		addModule(std::move(mod));
		return {};
	}
	if (name == "c") {
		auto mod = std::make_unique<CModule>(*this);
		if (toFill != nullptr) { *toFill = mod.get(); }
		addModule(std::move(mod));  // we don't care if it's actually added
		return {};
	}

	if (workspacePath().empty()) {
		res.addEntry("EUKN", "Cannot load module without a workspace path",
					 {{"Requested Module"}, gsl::to_string(name)});
		return res;
	}

	// find it in the workspace
	fs::path fullPath = workspacePath() / "src" / (gsl::to_string(name) + ".chigmod");

	if (!fs::is_regular_file(fullPath)) {
		res.addEntry(
			"EUKN", "Failed to find module",
			{{"Module Name", gsl::to_string(name)}, {"Workspace Path", workspacePath().string()}});
		return res;
	}

	// load the JSON
	nlohmann::json readJson = {};
	{
		fs::ifstream inFile{fullPath};

		inFile >> readJson;
	}

	JsonModule* toFillJson = nullptr;
	res += addModuleFromJson(name, readJson, &toFillJson);
	if (toFill != nullptr) { *toFill = toFillJson; }

	return res;
}

Result Context::addModuleFromJson(gsl::cstring_span<> fullName, const nlohmann::json& json,
								  JsonModule** toFill) {
	Result res;

	// make sure it's not already added
	{
		auto mod = moduleByFullName(fullName);
		if (mod != nullptr) {
			if (toFill != nullptr) {
				auto casted = dynamic_cast<JsonModule*>(mod);
				if (casted != nullptr) { *toFill = casted; }
			}
			return {};
		}
	}

	// Create the module
	JsonModule* cPtr = nullptr;
	{
		// parse module
		auto jmod = std::make_unique<JsonModule>(*this, gsl::to_string(fullName), json, &res);
		if (!res) { return res; }
		if (toFill != nullptr) { *toFill = jmod.get(); }

		cPtr	   = jmod.get();
		bool added = addModule(std::move(jmod));
		Expects(added);  // it really should be added
	}

	// load graphs
	res += cPtr->loadGraphs();

	return res;
}

bool Context::addModule(std::unique_ptr<ChigModule> modToAdd) noexcept {
	Expects(modToAdd != nullptr);

	// make sure it's unique
	auto ptr = moduleByFullName(modToAdd->fullName());
	if (ptr != nullptr) { return false; }

	mModules.push_back(std::move(modToAdd));

	Expects(modToAdd == nullptr);

	return true;
}

Result Context::typeFromModule(gsl::cstring_span<> module, gsl::cstring_span<> name,
							   DataType* toFill) noexcept {
	Expects(toFill != nullptr);

	Result res;

	ChigModule* mod = moduleByName(module);
	if (mod == nullptr) {
		res.addEntry("E36", "Could not find module", {{"module", gsl::to_string(module)}});
		return res;
	}

	*toFill = mod->typeFromName(name);
	if (!toFill->valid()) {
		res.addEntry("E37", "Could not find type in module",
					 {{"type", gsl::to_string(name)}, {"module", gsl::to_string(module)}});
	}

	return res;
}

Result Context::debugTypeFromModule(gsl::cstring_span<> module, gsl::cstring_span<> name,
									llvm::DIType** toFill) noexcept {
	Expects(toFill != nullptr);

	Result res;

	ChigModule* mod = moduleByName(module);
	if (mod == nullptr) {
		res.addEntry("E36", "Could not find module", {{"module", gsl::to_string(module)}});
		return res;
	}

	*toFill = mod->debugTypeFromName(name);
	if (*toFill == nullptr) {
		res.addEntry("E37", "Could not find type in module",
					 {{"type", gsl::to_string(name)}, {"module", gsl::to_string(module)}});
	}

	return res;
}

Result Context::nodeTypeFromModule(gsl::cstring_span<> moduleName, gsl::cstring_span<> typeName,
								   const nlohmann::json&	  data,
								   std::unique_ptr<NodeType>* toFill) noexcept {
	Result res;

	auto module = moduleByName(moduleName);
	if (module == nullptr) {
		res.addEntry("E36", "Could not find module", {{"module", gsl::to_string(moduleName)}});
		return res;
	}

	res += module->nodeTypeFromName(typeName, data, toFill);

	return res;
}

Result Context::compileModule(gsl::cstring_span<> fullName, std::unique_ptr<llvm::Module>* toFill) {
	Expects(toFill != nullptr);

	Result res;

	auto chigmod = moduleByFullName(fullName);

	if (chigmod == nullptr) {
		res.addEntry("E36", "Could not find module", {{"module", gsl::to_string(fullName)}});
		return res;
	}

	auto llmod = std::make_unique<llvm::Module>(gsl::to_string(fullName), llvmContext());

	// generate dependencies
	for (const auto& depName : chigmod->dependencies()) {
		std::unique_ptr<llvm::Module> compiledDep;
		res += compileModule(depName, &compiledDep);  // TODO: detect circular dependencies

		if (!res) { return res; }

		// link it in
#if LLVM_VERSION_MAJOR <= 3 && LLVM_VERSION_MINOR <= 7
        llvm::Linker::LinkModules(llmod.get(), compiledDep.get());
#else
		llvm::Linker::linkModules(*llmod, std::move(compiledDep));
#endif
	}

	res += chigmod->generateModule(*llmod);

	// set debug info version if it doesn't already have it
	if (llmod->getModuleFlag("Debug Info Version") == nullptr) {
		llmod->addModuleFlag(llvm::Module::Warning, "Debug Info Version",
							 llvm::DEBUG_METADATA_VERSION);
	}

	// verify the created module
	if (res) {
		std::string				 err;
		llvm::raw_string_ostream os(err);
		if (llvm::verifyModule(*llmod, &os)) {
			std::string moduleStr;
			{
				llvm::raw_string_ostream printerStr{moduleStr};
				llmod->print(printerStr, nullptr);
			}
			res.addEntry(
				"EINT", "Internal compiler error: Invalid module created",
				{{"Error", err}, {"Full Name", gsl::to_string(fullName)}, {"Module", moduleStr}});
		}
	}

	*toFill = std::move(llmod);

	return res;
}

std::string Context::fullModuleName(gsl::cstring_span<> shortName) const {
	auto mod = moduleByName(shortName);

	if (mod != nullptr) { return mod->fullName(); }

	return "";
}
fs::path workspaceFromChildPath(const fs::path& path) {
	fs::path ret = path;

	// initialize workspace directory
	// go up until it is a workspace
	while (!ret.empty() && !fs::is_regular_file(ret / ".chigraphworkspace")) {
		ret = ret.parent_path();
	}

	return ret;  // it's ok if it's empty
}

std::string stringifyLLVMType(llvm::Type* ty) {
	Expects(ty != nullptr);

	std::string data;
	{
		llvm::raw_string_ostream stream{data};
		ty->print(stream);
	}
	return data;
}

}  // namespace chig
<|endoftext|>


<commit_before>#ifndef ANIMATION_HPP_INCLUDED
#define ANIMATION_HPP_INCLUDED

#include <vector>
#include <string>
#include <glm/glm.hpp>

namespace Kvant {

    struct Frame {
        std::vector<int> bone_parents;
        std::vector<glm::vec3> bone_positions;
        std::vector<glm::quat> bone_rotations;
        std::vector<glm::mat4> bone_transforms;
        std::vector<glm::vec4> bone_inv_transforms;
    };

    struct Bone {
        std::string name;
        int parent;

        Bone(std::string n, int p) : name(n), parent(p) {}
    };

    struct Skeleton {
        std::vector<Bone> bones;
        Frame rest;

        int n_bones() const {
            return bones.size();
        }
    };

}

#endif // ANIMATION_HPP_INCLUDED
<commit_msg>Added proper implementation of basic skeleton operations<commit_after>#ifndef ANIMATION_HPP_INCLUDED
#define ANIMATION_HPP_INCLUDED

#include <vector>
#include <string>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

namespace Kvant {

    /**
     * The Frame stores the all the bone matrices for a frame
     * Frames have to be "baked" before use
     * Baking converts the raw bone data into bone tranformation matrices
     */
    struct Frame {
        std::vector<int> bone_parents; // Value of -1 equals no parent
        std::vector<glm::vec3> bone_positions;
        std::vector<glm::quat> bone_rotations;

        // The transform that moves the bone, from it's resting frame, to the new pose
        // This is what gets baked and pushed to the vertex shader
        std::vector<glm::mat4> bone_transforms;
        std::vector<glm::mat4> bone_inv_transforms;
        bool is_baked{false};

        glm::mat4 bone_transform(int i) {
            glm::mat4 parent;
            glm::mat4 ret;
            // Recursively get the parents bone transform
            if (this->bone_parents[i] != -1) {
                glm::mat4 parent = this->bone_transform(this->bone_parents[i]);
                ret *= parent; // Move bone to parent
            }
            // pos and rot are relative to parent
            glm::mat4 pos = glm::translate(glm::mat4(), this->bone_positions[i]);
            glm::mat4 rot = glm::mat4_cast(this->bone_rotations[i]);
            ret *= pos; // Add position offset from parent
            ret *= rot; // Add rotation offset from parent
            return ret;
        }

        void bake_transforms() {
            auto bones = bone_parents.size();
            this->bone_transforms.clear();
            this->bone_inv_transforms.clear();

            // iterate over all bones
            for (auto i = 0; i < bones; i++) {
                glm::mat4 t = bone_transform(i);
                this->bone_transforms.push_back(t);
                this->bone_inv_transforms.push_back(glm::inverse(t));
            }
            this->is_baked = true;
        }
    };

    /**
     * Represents a bone/joint in the skeleton
     */
    struct Bone {
        std::string name;
        int parent;       // The parent bone transforms it's child's transform

        Bone(std::string n, int p) : name(n), parent(p) {}
    };

    /**
     * The skeleton consists of a list of bones and the skeleton's resting keyframe
     */
    struct Skeleton {
        std::vector<Bone> bones;
        Frame rest;

        int n_bones() const {
            return bones.size();
        }
    };

    class Animation {
        public:
            Animation(std::string filename, const Skeleton& s, bool loop = true);

            void update(const Kvant::CoreContext& ctx) {
                _animation_time += ctx.elapsed;
            }

            void reset() {
                _animation_time = 0;
            }

            static std::unique_ptr<Frame> interpolate(const Frame& f0, const Frame& f1, float amount) {
                auto interpolated = std::make_unique<Frame>();
                interpolated.get()->bone_parents = f0.bone_parents;
                int n_bones = f0.bone_positions.size();
                for (int i = 0; i < n_bones; i++) {
                    interpolated.get()->bone_positions.push_back(
                        glm::lerp(f0.bone_positions[i], f1.bone_positions[i], amount)
                    );
                    interpolated.get()->bone_rotations.push_back(
                        glm::slerp(f0.bone_rotations[i], f1.bone_rotations[i], amount)
                    );
                }
                interpolated.get()->bake_transforms();
                return std::move(interpolated);
            }

            Frame current_frame() const {

            }

        private:
            Skeleton _skeleton;
            std::vector<Frame> _frames;
            mutable float _animation_time = 0;
            bool _loop{true};
    };

}

#endif // ANIMATION_HPP_INCLUDED
<|endoftext|>


<commit_before>#include <powerset.hpp>
#include <vector>
#include <iostream>

using iter::powerset;

int main() {
    std::vector<int> vec {1,2,3,4,5,6,7,8,9};
    for (auto v : powerset(vec)) {
        for (auto i : v) std::cout << i << " ";
        std::cout << std::endl;
    }
    std::cout << "with temporary\n";
    for (auto v : powerset(std::vector<int>{1,2,3})) {
        for (auto i : v) std::cout << i << " ";
        std::cout << std::endl;
    }
    std::cout << "with initializer_list\n";
    for (auto v : powerset({1,2,3})) {
        for (auto i : v) std::cout << i << " ";
        std::cout << std::endl;
    }
#if 0
#endif

    return 0;
}
<commit_msg>adds test with container of move-only objects<commit_after>#include "samples.hpp"
#include <powerset.hpp>
#include <range.hpp>
#include <vector>
#include <iostream>

using iter::powerset;

int main() {
    std::vector<int> vec {1,2,3,4,5,6,7,8,9};
    for (auto v : powerset(vec)) {
        for (auto i : v) std::cout << i << " ";
        std::cout << std::endl;
    }
    std::cout << "with temporary\n";
    for (auto v : powerset(std::vector<int>{1,2,3})) {
        for (auto i : v) std::cout << i << " ";
        std::cout << std::endl;
    }
    std::cout << "with initializer_list\n";
    for (auto v : powerset({1,2,3})) {
        for (auto i : v) std::cout << i << " ";
        std::cout << std::endl;
    }

    std::cout << "with container of move-only objects\n";
    std::vector<itertest::MoveOnly> mv;
    for (auto i : iter::range(3)) {
        mv.emplace_back(i);
    }

    return 0;
}
<|endoftext|>


<commit_before>#include "audio_output.hpp"
#include <thread>
#include <mutex>
#include <portaudio.h>
#include "../log.hpp"
#include "ring_buffer.hpp"
#include "sine_wave.hpp"
#include "mp3_stream.hpp"

template <typename SampleT>
struct data_type_table;

template <> struct data_type_table<short> { enum { value = paInt16 }; };
template <> struct data_type_table<float> { enum { value = paFloat32 }; };

template <typename SampleT>
struct audio_context {
    using stream_t = typename audio_output<SampleT>::stream_t;
    using buffer_t = typename stream_t::buffer_t;

    size_t channels;
    size_t sample_rate;
    size_t channel_frame_size;
    size_t buffer_size;

    ring_buffer<SampleT> sample_buffer;
    stream_t* stream_ptr;
    std::mutex context_mtx;
    std::atomic<bool> shutdown;

    audio_context() : stream_ptr(nullptr) { }
};

template <typename SampleT>
struct audio_output<SampleT>::state_t {
    std::thread audio_thread;
    audio_context<SampleT> context;
};

typedef int callback(const void* input, void* output, u_long frame_count,
    const PaStreamCallbackTimeInfo* time_info, PaStreamCallbackFlags status_flags,
    void* userdata);

int audio_output_callback_s16(const void* input, void* output, u_long frame_count,
        const PaStreamCallbackTimeInfo* time_info, PaStreamCallbackFlags status_flags,
        void* userdata) {
    short* out = static_cast<short*>(output);
    using context = audio_context<short>;
    context* context_ptr = static_cast<context*>(userdata);

    if(!context_ptr) {
        SM_LOG("Null context passed. Aborting");
        return paAbort;
    }

    static typename context::buffer_t buffer(context_ptr->buffer_size);
    size_t len = 0;

    {
        std::lock_guard<std::mutex> lock(context_ptr->context_mtx);
        len = context_ptr->sample_buffer.read(buffer.data(), context_ptr->buffer_size);
    }

    if(len == 0 || context_ptr->shutdown) {
        SM_LOG("Complete");
        return paComplete;
    }

    for(size_t i = 0; i != len; ++i) *out++ = buffer[i];
    return paContinue;
}

template <typename SampleT>
void audio_output<SampleT>::audio_thread_fnc(audio_output* parent_ptr) {
    SM_LOG("Starting", parent_ptr->channels(), parent_ptr->sample_rate(), parent_ptr->frame_size());

    auto context_ptr = &parent_ptr->s.context;

    context_ptr->channels = parent_ptr->channels();
    context_ptr->sample_rate = parent_ptr->sample_rate();
    context_ptr->channel_frame_size = parent_ptr->frame_size()/parent_ptr->channels();
    context_ptr->buffer_size = parent_ptr->frame_size();

    if(Pa_Initialize() != paNoError) {
        SM_LOG("Error initialising portaudio");
        return;
    }

    PaStreamParameters output_parms;
    output_parms.device = Pa_GetDefaultOutputDevice();
    if(output_parms.device == paNoDevice) {
        SM_LOG("Portaudio could not find a default playback device");
        return;
    }

    PaStream* pa_stream;
    PaError err = Pa_OpenDefaultStream(
            &pa_stream,
            0,
            int(parent_ptr->channels()),
            data_type_table<SampleT>::value,
            parent_ptr->sample_rate(),
            context_ptr->channel_frame_size,
            &audio_output_callback_s16,
            context_ptr
    );

    if(err != paNoError) {
        SM_LOG("Pa_OpenStream failed:", err, Pa_GetErrorText(err));
        if(pa_stream) Pa_CloseStream(pa_stream);
        return;
    }

    if(Pa_StartStream(pa_stream) != paNoError) {
        SM_LOG("Pa_StartStream failed:", err, Pa_GetErrorText(err));
        if(pa_stream) Pa_CloseStream(pa_stream);
        return;
    }

    // Initialise the ring_buffer

    // 44100 sample rate x 2 channels x 2 bytes per sample = 176400 bytes per second = 172 kB per second

    const size_t buf_size = 64*parent_ptr->frame_size();
    const size_t hbuf_size = buf_size / 2;
    const auto scan_ms = std::chrono::milliseconds(60);

    auto& context = parent_ptr->s.context;
    size_t cache_cur = 0;                                   // The cache cursor
    context.sample_buffer.resize(buf_size);                 // 64 kB
    typename stream_t::buffer_t sample_cache(hbuf_size);    // 32 kB

    while(Pa_IsStreamActive(pa_stream) > 0) {
        if(cache_cur == 0) {
            // Refill the cache with samples from the stream, the stream may possibly block on I/O
            cache_cur = context.stream_ptr->read(sample_cache, hbuf_size);
        }

        // Check, every 60 milliseconds, if the sample_buffer needs refilling
        {
            std::lock_guard<std::mutex> lock(context.context_mtx);
            if(context.sample_buffer.size() < context.sample_buffer.capacity()/2) { // If sample_buffer < 1/2
                context.sample_buffer.write(sample_cache.data(), cache_cur);
                cache_cur = 0;
            }
        }

        std::this_thread::sleep_for(scan_ms);
    }

    parent_ptr->audio_state_ = audio_state::AS_STOPPED;

    if(Pa_Terminate() != paNoError) {
        SM_LOG("Pa_Terminate error:", err, Pa_GetErrorText(err));
        return;
    }
}

template <typename SampleT>
audio_output<SampleT>::audio_output(stream_t* stream_ptr, size_t channels, size_t sample_rate, size_t frame_size)
        : audio_state_(audio_state::AS_STOPPED), channels_(channels), sample_rate_(sample_rate),
          frame_size_(frame_size), state_(new state_t()), s(*state_) {
    state_->context.stream_ptr = stream_ptr;
}

template <typename SampleT>
audio_output<SampleT>::~audio_output() {
    if(is_playing() || is_paused()) {
        SM_LOG("Warning: audio_output was not stopped");
        stop();
    }
}

template <typename SampleT>
void audio_output<SampleT>::set_stream(stream_t* stream_ptr) {
    if(is_stopped()) s.context.stream_ptr = stream_ptr;
}

template <typename SampleT>
typename audio_output<SampleT>::stream_t* audio_output<SampleT>::get_stream() const {
    return s.context.stream_ptr;
}

template <typename SampleT>
void audio_output<SampleT>::play() {
    if(is_playing() || is_paused()) return;
    SM_LOG("Starting audio_output");

    s.audio_thread = std::thread(audio_output<SampleT>::audio_thread_fnc, this);

    audio_state_ = audio_state::AS_PLAYING;
}

template <typename SampleT>
void audio_output<SampleT>::pause() {
    if(is_stopped()) return;
    SM_LOG("Pausing audio_output");

    audio_state_ = audio_state_ == audio_state::AS_PAUSED ? audio_state::AS_PLAYING : audio_state::AS_PAUSED;
}

template <typename SampleT>
void audio_output<SampleT>::stop() {
    if(is_stopped()) return;
    SM_LOG("Stopping audio_output");

    s.context.shutdown = true;
    s.audio_thread.join();

    audio_state_ = audio_state::AS_STOPPED;
}

template class audio_output<short>;
//template class audio_output<float>;
<commit_msg>- Changed to thread pointer<commit_after>#include "audio_output.hpp"
#include <thread>
#include <mutex>
#include <portaudio.h>
#include "../log.hpp"
#include "ring_buffer.hpp"
#include "sine_wave.hpp"
#include "mp3_stream.hpp"

template <typename SampleT>
struct data_type_table;

template <> struct data_type_table<short> { enum { value = paInt16 }; };
template <> struct data_type_table<float> { enum { value = paFloat32 }; };

template <typename SampleT>
struct audio_context {
    using stream_t = typename audio_output<SampleT>::stream_t;
    using buffer_t = typename stream_t::buffer_t;

    size_t channels;
    size_t sample_rate;
    size_t channel_frame_size;
    size_t buffer_size;

    ring_buffer<SampleT> sample_buffer;
    stream_t* stream_ptr;
    std::mutex context_mtx;
    std::atomic<bool> shutdown;

    audio_context() : stream_ptr(nullptr) { }
};

template <typename SampleT>
struct audio_output<SampleT>::state_t {
    std::unique_ptr<std::thread> audio_thread_ptr;
    audio_context<SampleT> context;
};

typedef int callback(const void* input, void* output, u_long frame_count,
    const PaStreamCallbackTimeInfo* time_info, PaStreamCallbackFlags status_flags,
    void* userdata);

int audio_output_callback_s16(const void* input, void* output, u_long frame_count,
        const PaStreamCallbackTimeInfo* time_info, PaStreamCallbackFlags status_flags,
        void* userdata) {
    short* out = static_cast<short*>(output);
    using context = audio_context<short>;
    context* context_ptr = static_cast<context*>(userdata);

    if(!context_ptr) {
        SM_LOG("Null context passed. Aborting");
        return paAbort;
    }

    static typename context::buffer_t buffer(context_ptr->buffer_size);
    size_t len = 0;

    {
        std::lock_guard<std::mutex> lock(context_ptr->context_mtx);
        len = context_ptr->sample_buffer.read(buffer.data(), context_ptr->buffer_size);
    }

    if(len == 0 || context_ptr->shutdown) {
        SM_LOG("Complete");
        return paComplete;
    }

    for(size_t i = 0; i != len; ++i) *out++ = buffer[i];
    return paContinue;
}

template <typename SampleT>
void audio_output<SampleT>::audio_thread_fnc(audio_output* parent_ptr) {
    SM_LOG("Starting", parent_ptr->channels(), parent_ptr->sample_rate(), parent_ptr->frame_size());

    auto context_ptr = &parent_ptr->s.context;

    context_ptr->channels = parent_ptr->channels();
    context_ptr->sample_rate = parent_ptr->sample_rate();
    context_ptr->channel_frame_size = parent_ptr->frame_size()/parent_ptr->channels();
    context_ptr->buffer_size = parent_ptr->frame_size();

    if(Pa_Initialize() != paNoError) {
        SM_LOG("Error initialising portaudio");
        return;
    }

    PaStreamParameters output_parms;
    output_parms.device = Pa_GetDefaultOutputDevice();
    if(output_parms.device == paNoDevice) {
        SM_LOG("Portaudio could not find a default playback device");
        return;
    }

    PaStream* pa_stream;
    PaError err = Pa_OpenDefaultStream(
            &pa_stream,
            0,
            int(parent_ptr->channels()),
            data_type_table<SampleT>::value,
            parent_ptr->sample_rate(),
            context_ptr->channel_frame_size,
            &audio_output_callback_s16,
            context_ptr
    );

    if(err != paNoError) {
        SM_LOG("Pa_OpenStream failed:", err, Pa_GetErrorText(err));
        if(pa_stream) Pa_CloseStream(pa_stream);
        return;
    }

    if(Pa_StartStream(pa_stream) != paNoError) {
        SM_LOG("Pa_StartStream failed:", err, Pa_GetErrorText(err));
        if(pa_stream) Pa_CloseStream(pa_stream);
        return;
    }

    // Initialise the ring_buffer

    // 44100 sample rate x 2 channels x 2 bytes per sample = 176400 bytes per second = 172 kB per second

    const size_t buf_size = 64*parent_ptr->frame_size();
    const size_t hbuf_size = buf_size / 2;
    const auto scan_ms = std::chrono::milliseconds(60);

    auto& context = parent_ptr->s.context;
    size_t cache_cur = 0;                                   // The cache cursor
    context.sample_buffer.resize(buf_size);                 // 64 kB
    typename stream_t::buffer_t sample_cache(hbuf_size);    // 32 kB

    while(Pa_IsStreamActive(pa_stream) > 0) {
        if(cache_cur == 0) {
            // Refill the cache with samples from the stream, the stream may possibly block on I/O
            cache_cur = context.stream_ptr->read(sample_cache, hbuf_size);
        }

        // Check, every 60 milliseconds, if the sample_buffer needs refilling
        {
            std::lock_guard<std::mutex> lock(context.context_mtx);
            if(context.sample_buffer.size() < context.sample_buffer.capacity()/2) { // If sample_buffer < 1/2
                context.sample_buffer.write(sample_cache.data(), cache_cur);
                cache_cur = 0;
            }
        }

        std::this_thread::sleep_for(scan_ms);
    }

    parent_ptr->audio_state_ = audio_state::AS_STOPPED;

    if(Pa_Terminate() != paNoError) {
        SM_LOG("Pa_Terminate error:", err, Pa_GetErrorText(err));
        return;
    }
}

template <typename SampleT>
audio_output<SampleT>::audio_output(stream_t* stream_ptr, size_t channels, size_t sample_rate, size_t frame_size)
        : audio_state_(audio_state::AS_STOPPED), channels_(channels), sample_rate_(sample_rate),
          frame_size_(frame_size), state_(new state_t()), s(*state_) {
    state_->context.stream_ptr = stream_ptr;
}

template <typename SampleT>
audio_output<SampleT>::~audio_output() {
    if(is_playing() || is_paused()) {
        SM_LOG("Warning: audio_output was not stopped");
        stop();
    }
}

template <typename SampleT>
void audio_output<SampleT>::set_stream(stream_t* stream_ptr) {
    if(is_stopped()) s.context.stream_ptr = stream_ptr;
}

template <typename SampleT>
typename audio_output<SampleT>::stream_t* audio_output<SampleT>::get_stream() const {
    return s.context.stream_ptr;
}

template <typename SampleT>
void audio_output<SampleT>::play() {
    if(is_playing() || is_paused()) return;
    SM_LOG("Starting audio_output");

    s.audio_thread_ptr = std::make_unique<std::thread>(audio_output<SampleT>::audio_thread_fnc, this);
    audio_state_ = audio_state::AS_PLAYING;
}

template <typename SampleT>
void audio_output<SampleT>::pause() {
    if(is_stopped()) return;
    SM_LOG("Pausing audio_output");

    audio_state_ = audio_state_ == audio_state::AS_PAUSED ? audio_state::AS_PLAYING : audio_state::AS_PAUSED;
}

template <typename SampleT>
void audio_output<SampleT>::stop() {
    if(is_stopped()) return;
    SM_LOG("Stopping audio_output");

    s.context.shutdown = true;
    s.audio_thread_ptr->join();
    s.audio_thread_ptr.reset(nullptr);

    audio_state_ = audio_state::AS_STOPPED;
}

template class audio_output<short>;
//template class audio_output<float>;
<|endoftext|>


<commit_before>#include "Optimizer.h"

#include "preprocessor/llvm_includes_start.h"
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/Transforms/Utils/BasicBlockUtils.h>
#include "preprocessor/llvm_includes_end.h"

#include "Arith256.h"
#include "Type.h"

namespace dev
{
namespace eth
{
namespace jit
{

namespace
{

class LongJmpEliminationPass: public llvm::FunctionPass
{
	static char ID;

public:
	LongJmpEliminationPass():
		llvm::FunctionPass(ID)
	{}

	virtual bool runOnFunction(llvm::Function& _func) override;
};

char LongJmpEliminationPass::ID = 0;

bool LongJmpEliminationPass::runOnFunction(llvm::Function& _func)
{
	if (&_func != _func.getParent()->begin())
		return false;

	auto& mainFunc = _func;
	auto& ctx = _func.getContext();
	auto abortCode = llvm::ConstantInt::get(llvm::Type::getInt32Ty(ctx), -1);

	auto& exitBB = mainFunc.back();
	assert(exitBB.getName() == "Exit");
	auto retPhi = llvm::cast<llvm::PHINode>(&exitBB.front());

	auto modified = false;
	for (auto bbIt = mainFunc.begin(); bbIt != mainFunc.end(); ++bbIt)
	{
		if (auto term = llvm::dyn_cast<llvm::UnreachableInst>(bbIt->getTerminator()))
		{
			auto longjmp = term->getPrevNode();
			assert(llvm::isa<llvm::CallInst>(longjmp));
			retPhi->addIncoming(abortCode, bbIt);
			llvm::ReplaceInstWithInst(term, llvm::BranchInst::Create(&exitBB));
			longjmp->eraseFromParent();
			modified = true;
		}
	}

	return modified;
}

}

bool optimize(llvm::Module& _module)
{
	auto pm = llvm::legacy::PassManager{};
	pm.add(llvm::createFunctionInliningPass(2, 2));
	pm.add(new LongJmpEliminationPass{}); 				// TODO: Takes a lot of time with little effect
	pm.add(llvm::createCFGSimplificationPass());
	pm.add(llvm::createInstructionCombiningPass());
	pm.add(llvm::createAggressiveDCEPass());
	pm.add(llvm::createLowerSwitchPass());
	return pm.run(_module);
}

namespace
{

class LowerEVMPass: public llvm::BasicBlockPass
{
	static char ID;

public:
	LowerEVMPass():
		llvm::BasicBlockPass(ID)
	{}

	virtual bool runOnBasicBlock(llvm::BasicBlock& _bb) override;

	using llvm::BasicBlockPass::doFinalization;
	virtual bool doFinalization(llvm::Module& _module) override;
};

char LowerEVMPass::ID = 0;

bool LowerEVMPass::runOnBasicBlock(llvm::BasicBlock& _bb)
{
	auto modified = false;
	auto module = _bb.getParent()->getParent();
	auto i512Ty = llvm::IntegerType::get(_bb.getContext(), 512);
	for (auto it = _bb.begin(); it != _bb.end(); )
	{
		auto& inst = *it++;
		llvm::Function* func = nullptr;
		if (inst.getType() == Type::Word)
		{
			switch (inst.getOpcode())
			{
			case llvm::Instruction::Mul:
				func = Arith256::getMulFunc(*module);
				break;

			case llvm::Instruction::UDiv:
				func = Arith256::getUDiv256Func(*module);
				break;

			case llvm::Instruction::URem:
				func = Arith256::getURem256Func(*module);
				break;

			case llvm::Instruction::SDiv:
				func = Arith256::getSDiv256Func(*module);
				break;

			case llvm::Instruction::SRem:
				func = Arith256::getSRem256Func(*module);
				break;
			}
		}
		else if (inst.getType() == i512Ty)
		{
			switch (inst.getOpcode())
			{
			case llvm::Instruction::URem:
				func = Arith256::getURem512Func(*module);
				break;
			}
		}

		if (func)
		{
			auto call = llvm::CallInst::Create(func, {inst.getOperand(0), inst.getOperand(1)}, "", &inst);
			inst.replaceAllUsesWith(call);
			inst.eraseFromParent();
			modified = true;
		}
	}
	return modified;
}

bool LowerEVMPass::doFinalization(llvm::Module&)
{
	return false;
}

}

bool prepare(llvm::Module& _module)
{
	auto pm = llvm::legacy::PassManager{};
	pm.add(llvm::createCFGSimplificationPass());
	pm.add(llvm::createDeadCodeEliminationPass());
	pm.add(new LowerEVMPass{});
	return pm.run(_module);
}

}
}
}
<commit_msg>Improve coding of 256-bit arithmetic lowering pass.<commit_after>#include "Optimizer.h"

#include "preprocessor/llvm_includes_start.h"
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/Transforms/Utils/BasicBlockUtils.h>
#include "preprocessor/llvm_includes_end.h"

#include "Arith256.h"
#include "Type.h"

namespace dev
{
namespace eth
{
namespace jit
{

namespace
{

class LongJmpEliminationPass: public llvm::FunctionPass
{
	static char ID;

public:
	LongJmpEliminationPass():
		llvm::FunctionPass(ID)
	{}

	virtual bool runOnFunction(llvm::Function& _func) override;
};

char LongJmpEliminationPass::ID = 0;

bool LongJmpEliminationPass::runOnFunction(llvm::Function& _func)
{
	if (&_func != _func.getParent()->begin())
		return false;

	auto& mainFunc = _func;
	auto& ctx = _func.getContext();
	auto abortCode = llvm::ConstantInt::get(llvm::Type::getInt32Ty(ctx), -1);

	auto& exitBB = mainFunc.back();
	assert(exitBB.getName() == "Exit");
	auto retPhi = llvm::cast<llvm::PHINode>(&exitBB.front());

	auto modified = false;
	for (auto bbIt = mainFunc.begin(); bbIt != mainFunc.end(); ++bbIt)
	{
		if (auto term = llvm::dyn_cast<llvm::UnreachableInst>(bbIt->getTerminator()))
		{
			auto longjmp = term->getPrevNode();
			assert(llvm::isa<llvm::CallInst>(longjmp));
			retPhi->addIncoming(abortCode, bbIt);
			llvm::ReplaceInstWithInst(term, llvm::BranchInst::Create(&exitBB));
			longjmp->eraseFromParent();
			modified = true;
		}
	}

	return modified;
}

}

bool optimize(llvm::Module& _module)
{
	auto pm = llvm::legacy::PassManager{};
	pm.add(llvm::createFunctionInliningPass(2, 2));
	pm.add(new LongJmpEliminationPass{}); 				// TODO: Takes a lot of time with little effect
	pm.add(llvm::createCFGSimplificationPass());
	pm.add(llvm::createInstructionCombiningPass());
	pm.add(llvm::createAggressiveDCEPass());
	pm.add(llvm::createLowerSwitchPass());
	return pm.run(_module);
}

namespace
{

class LowerEVMPass: public llvm::BasicBlockPass
{
	static char ID;

public:
	LowerEVMPass():
		llvm::BasicBlockPass(ID)
	{}

	virtual bool runOnBasicBlock(llvm::BasicBlock& _bb) override;

	using llvm::BasicBlockPass::doFinalization;
	virtual bool doFinalization(llvm::Module& _module) override;
};

char LowerEVMPass::ID = 0;

bool LowerEVMPass::runOnBasicBlock(llvm::BasicBlock& _bb)
{
	auto modified = false;
	auto module = _bb.getParent()->getParent();
	auto i512Ty = llvm::IntegerType::get(_bb.getContext(), 512);
	for (auto it = _bb.begin(); it != _bb.end(); ++it)
	{
		auto& inst = *it;
		llvm::Function* func = nullptr;
		if (inst.getType() == Type::Word)
		{
			switch (inst.getOpcode())
			{
			case llvm::Instruction::Mul:
				func = Arith256::getMulFunc(*module);
				break;

			case llvm::Instruction::UDiv:
				func = Arith256::getUDiv256Func(*module);
				break;

			case llvm::Instruction::URem:
				func = Arith256::getURem256Func(*module);
				break;

			case llvm::Instruction::SDiv:
				func = Arith256::getSDiv256Func(*module);
				break;

			case llvm::Instruction::SRem:
				func = Arith256::getSRem256Func(*module);
				break;
			}
		}
		else if (inst.getType() == i512Ty)
		{
			switch (inst.getOpcode())
			{
			case llvm::Instruction::URem:
				func = Arith256::getURem512Func(*module);
				break;
			}
		}

		if (func)
		{
			auto call = llvm::CallInst::Create(func, {inst.getOperand(0), inst.getOperand(1)});
			llvm::ReplaceInstWithInst(_bb.getInstList(), it, call);
			modified = true;
		}
	}
	return modified;
}

bool LowerEVMPass::doFinalization(llvm::Module&)
{
	return false;
}

}

bool prepare(llvm::Module& _module)
{
	auto pm = llvm::legacy::PassManager{};
	pm.add(llvm::createCFGSimplificationPass());
	pm.add(llvm::createDeadCodeEliminationPass());
	pm.add(new LowerEVMPass{});
	return pm.run(_module);
}

}
}
}
<|endoftext|>


<commit_before>/*
Copyright 2016 Fixstars Corporation

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

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

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

#include <iostream>
#include <iomanip>
#include <chrono>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cuda_runtime.h>

#include <libsgm.h>

#define ASSERT_MSG(expr, msg) \
	if (!(expr)) { \
		std::cerr << msg << std::endl; \
		std::exit(EXIT_FAILURE); \
	} \

struct device_buffer
{
	device_buffer() : data(nullptr) {}
	device_buffer(size_t count) { allocate(count); }
	void allocate(size_t count) { cudaMalloc(&data, count); }
	~device_buffer() { cudaFree(data); }
	void* data;
};

int main(int argc, char* argv[])
{
	if (argc < 3) {
		std::cout << "usage: " << argv[0] << " left_img right_img [disp_size] [out_depth] [subpixel_enable(0: false, 1:true)] [iterations]" << std::endl;
		std::exit(EXIT_FAILURE);
	}

	cv::Mat I1 = cv::imread(argv[1], -1);
	cv::Mat I2 = cv::imread(argv[2], -1);

	ASSERT_MSG(!I1.empty() && !I2.empty(), "imread failed.");
	ASSERT_MSG(I1.size() == I2.size() && I1.type() == I2.type(), "input images must be same size and type.");
	ASSERT_MSG(I1.type() == CV_8U || I1.type() == CV_16U, "input image format must be CV_8U or CV_16U.");

	const int disp_size = argc > 3 ? std::stoi(argv[3]) : 128;
	const int out_depth = argc > 4 ? std::stoi(argv[4]) : 8;
	const bool subpixel = argc > 5 ? std::stoi(argv[5]) != 0 : false;

	ASSERT_MSG(disp_size == 64 || disp_size == 128, "disparity size must be 64 or 128.");
	if (subpixel) {
		ASSERT_MSG(out_depth == 16, "output depth bits must be 16 if subpixel option is enabled.");
	} else {
		ASSERT_MSG(out_depth == 8 || out_depth == 16, "output depth bits must be 8 or 16");
	}
	const int iterations = argc > 6 ? std::stoi(argv[6]) : 100;

	const int width = I1.cols;
	const int height = I1.rows;

	const int input_depth = I1.type() == CV_8U ? 8 : 16;
	const int input_bytes = input_depth * width * height / 8;
	const int output_bytes = out_depth * width * height / 8;

	const sgm::StereoSGM::Parameters params{10, 120, 0.95f, subpixel};

	sgm::StereoSGM sgm(width, height, disp_size, input_depth, out_depth, sgm::EXECUTE_INOUT_CUDA2CUDA, params);

	device_buffer d_I1(input_bytes), d_I2(input_bytes), d_disparity(output_bytes);
	cudaMemcpy(d_I1.data, I1.data, input_bytes, cudaMemcpyHostToDevice);
	cudaMemcpy(d_I2.data, I2.data, input_bytes, cudaMemcpyHostToDevice);

	cudaDeviceProp prop;
	int version;
	cudaGetDeviceProperties(&prop, 0);
	cudaRuntimeGetVersion(&version);

	// show settings
	std::cout << "# Settings" << std::endl;
	std::cout << "device name         : " << prop.name << std::endl;
	std::cout << "CUDA runtime version: " << version << std::endl;
	std::cout << "image size          : " << I1.size() << std::endl;
	std::cout << "disparity size      : " << disp_size << std::endl;
	std::cout << "output_bytes        : " << out_depth << std::endl;
	std::cout << "subpixel option     : " << (subpixel ? "true" : "false") << std::endl;
	std::cout << "sgm path            : " << "8 path" << std::endl;
	std::cout << "iterations          : " << iterations << std::endl;
	std::cout << std::endl;

	// run benchmark
	std::cout << "Running benchmark..." << std::endl;
	uint64_t sum = 0;
	for (int i = 0; i <= iterations; i++) {
		const auto t1 = std::chrono::system_clock::now();

		sgm.execute(d_I1.data, d_I2.data, d_disparity.data);
		cudaDeviceSynchronize();

		const auto t2 = std::chrono::system_clock::now();
		if (i > 0)
			sum += std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
	}
	std::cout << "Done." << std::endl << std::endl;

	// show results
	const double time_millisec = 1e-3 * sum / iterations;
	const double fps = 1e3 / time_millisec;
	std::cout << "# Results" << std::endl;
	std::cout.setf(std::ios::fixed);
	std::cout << std::setprecision(1) << "Processing Time[Milliseconds]: " << time_millisec << std::endl;
	std::cout << std::setprecision(1) << "FPS                          : " << fps << std::endl;
	std::cout << std::endl;

	// save disparity image
	cv::Mat disparity(height, width, out_depth == 8 ? CV_8U : CV_16U);
	cudaMemcpy(disparity.data, d_disparity.data, output_bytes, cudaMemcpyDeviceToHost);
	disparity *= 255. / disp_size;
	cv::imwrite("disparity.png", disparity);

	return 0;
}
<commit_msg>Fix displaying variable at benchmark sample<commit_after>/*
Copyright 2016 Fixstars Corporation

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

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

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

#include <iostream>
#include <iomanip>
#include <chrono>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cuda_runtime.h>

#include <libsgm.h>

#define ASSERT_MSG(expr, msg) \
	if (!(expr)) { \
		std::cerr << msg << std::endl; \
		std::exit(EXIT_FAILURE); \
	} \

struct device_buffer
{
	device_buffer() : data(nullptr) {}
	device_buffer(size_t count) { allocate(count); }
	void allocate(size_t count) { cudaMalloc(&data, count); }
	~device_buffer() { cudaFree(data); }
	void* data;
};

int main(int argc, char* argv[])
{
	if (argc < 3) {
		std::cout << "usage: " << argv[0] << " left_img right_img [disp_size] [out_depth] [subpixel_enable(0: false, 1:true)] [iterations]" << std::endl;
		std::exit(EXIT_FAILURE);
	}

	cv::Mat I1 = cv::imread(argv[1], -1);
	cv::Mat I2 = cv::imread(argv[2], -1);

	ASSERT_MSG(!I1.empty() && !I2.empty(), "imread failed.");
	ASSERT_MSG(I1.size() == I2.size() && I1.type() == I2.type(), "input images must be same size and type.");
	ASSERT_MSG(I1.type() == CV_8U || I1.type() == CV_16U, "input image format must be CV_8U or CV_16U.");

	const int disp_size = argc > 3 ? std::stoi(argv[3]) : 128;
	const int out_depth = argc > 4 ? std::stoi(argv[4]) : 8;
	const bool subpixel = argc > 5 ? std::stoi(argv[5]) != 0 : false;

	ASSERT_MSG(disp_size == 64 || disp_size == 128, "disparity size must be 64 or 128.");
	if (subpixel) {
		ASSERT_MSG(out_depth == 16, "output depth bits must be 16 if subpixel option is enabled.");
	} else {
		ASSERT_MSG(out_depth == 8 || out_depth == 16, "output depth bits must be 8 or 16");
	}
	const int iterations = argc > 6 ? std::stoi(argv[6]) : 100;

	const int width = I1.cols;
	const int height = I1.rows;

	const int input_depth = I1.type() == CV_8U ? 8 : 16;
	const int input_bytes = input_depth * width * height / 8;
	const int output_bytes = out_depth * width * height / 8;

	const sgm::StereoSGM::Parameters params{10, 120, 0.95f, subpixel};

	sgm::StereoSGM sgm(width, height, disp_size, input_depth, out_depth, sgm::EXECUTE_INOUT_CUDA2CUDA, params);

	device_buffer d_I1(input_bytes), d_I2(input_bytes), d_disparity(output_bytes);
	cudaMemcpy(d_I1.data, I1.data, input_bytes, cudaMemcpyHostToDevice);
	cudaMemcpy(d_I2.data, I2.data, input_bytes, cudaMemcpyHostToDevice);

	cudaDeviceProp prop;
	int version;
	cudaGetDeviceProperties(&prop, 0);
	cudaRuntimeGetVersion(&version);

	// show settings
	std::cout << "# Settings" << std::endl;
	std::cout << "device name         : " << prop.name << std::endl;
	std::cout << "CUDA runtime version: " << version << std::endl;
	std::cout << "image size          : " << I1.size() << std::endl;
	std::cout << "disparity size      : " << disp_size << std::endl;
	std::cout << "output depth        : " << out_depth << std::endl;
	std::cout << "subpixel option     : " << (subpixel ? "true" : "false") << std::endl;
	std::cout << "sgm path            : " << "8 path" << std::endl;
	std::cout << "iterations          : " << iterations << std::endl;
	std::cout << std::endl;

	// run benchmark
	std::cout << "Running benchmark..." << std::endl;
	uint64_t sum = 0;
	for (int i = 0; i <= iterations; i++) {
		const auto t1 = std::chrono::system_clock::now();

		sgm.execute(d_I1.data, d_I2.data, d_disparity.data);
		cudaDeviceSynchronize();

		const auto t2 = std::chrono::system_clock::now();
		if (i > 0)
			sum += std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
	}
	std::cout << "Done." << std::endl << std::endl;

	// show results
	const double time_millisec = 1e-3 * sum / iterations;
	const double fps = 1e3 / time_millisec;
	std::cout << "# Results" << std::endl;
	std::cout.setf(std::ios::fixed);
	std::cout << std::setprecision(1) << "Processing Time[Milliseconds]: " << time_millisec << std::endl;
	std::cout << std::setprecision(1) << "FPS                          : " << fps << std::endl;
	std::cout << std::endl;

	// save disparity image
	cv::Mat disparity(height, width, out_depth == 8 ? CV_8U : CV_16U);
	cudaMemcpy(disparity.data, d_disparity.data, output_bytes, cudaMemcpyDeviceToHost);
	disparity *= 255. / disp_size;
	cv::imwrite("disparity.png", disparity);

	return 0;
}
<|endoftext|>


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

#include <utils/logging.h>
#include <thread>

#include "Game.h"

Game::Game(AAssetManager &assetManager): mAssetManager(assetManager) {
}

void Game::start() {

    // Load the RAW PCM data files for both the clap sound and backing track into memory.
    std::unique_ptr<AAssetDataSource> mClapSource(AAssetDataSource::newFromAssetManager(mAssetManager,
        "CLAP.raw",
        oboe::ChannelCount::Stereo));
    if (mClapSource.get() == nullptr){
        LOGE("Could not load source data for clap sound");
        return;
    }
    mClap = std::make_shared<Player>(std::move(mClapSource));

    std::unique_ptr<AAssetDataSource> mBackingTrackSource(AAssetDataSource::newFromAssetManager(mAssetManager,
        "FUNKY_HOUSE.raw",
        oboe::ChannelCount::Stereo));
    if (mBackingTrackSource.get() == nullptr){
        LOGE("Could not load source data for backing track");
        return;
    }
    mBackingTrack = std::make_shared<Player>(std::move(mBackingTrackSource));
    mBackingTrack->setPlaying(true);
    mBackingTrack->setLooping(true);

    // Add the clap and backing track sounds to a mixer so that they can be played together
    // simultaneously using a single audio stream.
    mMixer.addTrack(mClap);
    mMixer.addTrack(mBackingTrack);

    // Add the audio frame numbers on which the clap sound should be played to the clap event queue.
    // The backing track tempo is 120 beats per minute, which is 2 beats per second. At a sample
    // rate of 48000 frames per second this means a beat occurs every 24000 frames, starting at
    // zero. So the first 3 beats are: 0, 24000, 48000
    mClapEvents.push(0);
    mClapEvents.push(24000);
    mClapEvents.push(48000);

    // We want the user to tap on the screen exactly 4 beats after the first clap. 4 beats is
    // 96000 frames, so we just add 96000 to the above frame numbers.
    mClapWindows.push(96000);
    mClapWindows.push(120000);
    mClapWindows.push(144000);

    // Create a builder
    AudioStreamBuilder builder;
    builder.setFormat(AudioFormat::I16);
    builder.setChannelCount(2);
    builder.setSampleRate(kSampleRateHz);
    builder.setCallback(this);
    builder.setPerformanceMode(PerformanceMode::LowLatency);
    builder.setSharingMode(SharingMode::Exclusive);

    Result result = builder.openStream(&mAudioStream);
    if (result != Result::OK){
        LOGE("Failed to open stream. Error: %s", convertToText(result));
    }

    // Reduce stream latency by setting the buffer size to a multiple of the burst size
    auto setBufferSizeResult = mAudioStream->setBufferSizeInFrames(
            mAudioStream->getFramesPerBurst() * kBufferSizeInBursts);
    if (setBufferSizeResult != Result::OK){
        LOGW("Failed to set buffer size. Error: %s", convertToText(setBufferSizeResult.error()));
    }

    result = mAudioStream->requestStart();
    if (result != Result::OK){
        LOGE("Failed to start stream. Error: %s", convertToText(result));
    }
}

void Game::stop(){

    if (mAudioStream != nullptr){
        mAudioStream->close();
        mAudioStream = nullptr;
    }
}

void Game::tap(int64_t eventTimeAsUptime) {
    mClap->setPlaying(true);

    int64_t nextClapWindowFrame;
    if (mClapWindows.pop(nextClapWindowFrame)){

        int64_t frameDelta = nextClapWindowFrame - mCurrentFrame;
        int64_t timeDelta = convertFramesToMillis(frameDelta, kSampleRateHz);
        int64_t windowTime = mLastUpdateTime + timeDelta;
        TapResult result = getTapResult(eventTimeAsUptime, windowTime);
        mUiEvents.push(result);
    }
}

void Game::tick(){

    TapResult r;
    if (mUiEvents.pop(r)) {
        renderEvent(r);
    } else {
        SetGLScreenColor(kScreenBackgroundColor);
    }
}

void Game::onSurfaceCreated() {
    SetGLScreenColor(kScreenBackgroundColor);
}

void Game::onSurfaceChanged(int widthInPixels, int heightInPixels) {
}

void Game::onSurfaceDestroyed() {
}

DataCallbackResult Game::onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) {

    int64_t nextClapEvent;

    for (int i = 0; i < numFrames; ++i) {

        if (mClapEvents.peek(nextClapEvent) && mCurrentFrame == nextClapEvent){
            mClap->setPlaying(true);
            mClapEvents.pop(nextClapEvent);
        }
        mMixer.renderAudio(static_cast<int16_t*>(audioData)+(kChannelCount*i), 1);
        mCurrentFrame++;
    }

    mLastUpdateTime = nowUptimeMillis();

    return DataCallbackResult::Continue;
}

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

#include <utils/logging.h>
#include <thread>

#include "Game.h"

Game::Game(AAssetManager &assetManager): mAssetManager(assetManager) {
}

void Game::start() {

    // Load the RAW PCM data files for both the clap sound and backing track into memory.
    std::shared_ptr<AAssetDataSource> mClapSource(AAssetDataSource::newFromAssetManager(mAssetManager,
        "CLAP.raw",
        oboe::ChannelCount::Stereo));
    if (mClapSource == nullptr){
        LOGE("Could not load source data for clap sound");
        return;
    }
    mClap = std::make_shared<Player>(mClapSource);

    std::shared_ptr<AAssetDataSource> mBackingTrackSource(AAssetDataSource::newFromAssetManager(mAssetManager,
        "FUNKY_HOUSE.raw",
        oboe::ChannelCount::Stereo));
    if (mBackingTrackSource == nullptr){
        LOGE("Could not load source data for backing track");
        return;
    }
    mBackingTrack = std::make_shared<Player>(mBackingTrackSource);
    mBackingTrack->setPlaying(true);
    mBackingTrack->setLooping(true);

    // Add the clap and backing track sounds to a mixer so that they can be played together
    // simultaneously using a single audio stream.
    mMixer.addTrack(mClap);
    mMixer.addTrack(mBackingTrack);

    // Add the audio frame numbers on which the clap sound should be played to the clap event queue.
    // The backing track tempo is 120 beats per minute, which is 2 beats per second. At a sample
    // rate of 48000 frames per second this means a beat occurs every 24000 frames, starting at
    // zero. So the first 3 beats are: 0, 24000, 48000
    mClapEvents.push(0);
    mClapEvents.push(24000);
    mClapEvents.push(48000);

    // We want the user to tap on the screen exactly 4 beats after the first clap. 4 beats is
    // 96000 frames, so we just add 96000 to the above frame numbers.
    mClapWindows.push(96000);
    mClapWindows.push(120000);
    mClapWindows.push(144000);

    // Create a builder
    AudioStreamBuilder builder;
    builder.setFormat(AudioFormat::I16);
    builder.setChannelCount(2);
    builder.setSampleRate(kSampleRateHz);
    builder.setCallback(this);
    builder.setPerformanceMode(PerformanceMode::LowLatency);
    builder.setSharingMode(SharingMode::Exclusive);

    Result result = builder.openStream(&mAudioStream);
    if (result != Result::OK){
        LOGE("Failed to open stream. Error: %s", convertToText(result));
    }

    // Reduce stream latency by setting the buffer size to a multiple of the burst size
    auto setBufferSizeResult = mAudioStream->setBufferSizeInFrames(
            mAudioStream->getFramesPerBurst() * kBufferSizeInBursts);
    if (setBufferSizeResult != Result::OK){
        LOGW("Failed to set buffer size. Error: %s", convertToText(setBufferSizeResult.error()));
    }

    result = mAudioStream->requestStart();
    if (result != Result::OK){
        LOGE("Failed to start stream. Error: %s", convertToText(result));
    }
}

void Game::stop(){

    if (mAudioStream != nullptr){
        mAudioStream->close();
        delete mAudioStream;
        mAudioStream = nullptr;
    }
}

void Game::tap(int64_t eventTimeAsUptime) {
    mClap->setPlaying(true);

    int64_t nextClapWindowFrame;
    if (mClapWindows.pop(nextClapWindowFrame)){

        int64_t frameDelta = nextClapWindowFrame - mCurrentFrame;
        int64_t timeDelta = convertFramesToMillis(frameDelta, kSampleRateHz);
        int64_t windowTime = mLastUpdateTime + timeDelta;
        TapResult result = getTapResult(eventTimeAsUptime, windowTime);
        mUiEvents.push(result);
    }
}

void Game::tick(){

    TapResult r;
    if (mUiEvents.pop(r)) {
        renderEvent(r);
    } else {
        SetGLScreenColor(kScreenBackgroundColor);
    }
}

void Game::onSurfaceCreated() {
    SetGLScreenColor(kScreenBackgroundColor);
}

void Game::onSurfaceChanged(int widthInPixels, int heightInPixels) {
}

void Game::onSurfaceDestroyed() {
}

DataCallbackResult Game::onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) {

    int64_t nextClapEvent;

    for (int i = 0; i < numFrames; ++i) {

        if (mClapEvents.peek(nextClapEvent) && mCurrentFrame == nextClapEvent){
            mClap->setPlaying(true);
            mClapEvents.pop(nextClapEvent);
        }
        mMixer.renderAudio(static_cast<int16_t*>(audioData)+(kChannelCount*i), 1);
        mCurrentFrame++;
    }

    mLastUpdateTime = nowUptimeMillis();

    return DataCallbackResult::Continue;
}

<|endoftext|>


<commit_before><commit_msg>GPU Calc: Optimized RANDOM<commit_after><|endoftext|>


<commit_before>#include <QtGui/QVBoxLayout>

#include "listWidget.h"

using namespace qReal;

ListWidget::ListWidget(QWidget *parent)
	: QWidget(parent)
	, mListWidget(new QListWidget())
	, mOkButton(new QPushButton(tr("&OK")))
{
	mOkButton->setDisabled(true);

	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addWidget(mListWidget);
	mainLayout->addWidget(mOkButton);

	setLayout(mainLayout);

	connect(mListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(okActivate()));
	connect(mOkButton, SIGNAL(clicked()), this, SLOT(okButtonHandler()));
	connect(mListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*))
			, this, SLOT(doubleClickHandler(QListWidgetItem*)));
}

void ListWidget::addItem(QString const &text, QString const &userData, QString const &toolTip)
{
	QListWidgetItem *currentItem = new QListWidgetItem(text, mListWidget);
	currentItem->setData(Qt::UserRole, userData);
	currentItem->setToolTip(toolTip);
	mListWidget->addItem(currentItem);
}

void ListWidget::highlightFirstItem()
{
	if (count() == 0) {
		return;
	}
	mListWidget->setCurrentRow(0);
}

int ListWidget::count()
{
	return mListWidget->count();
}

void ListWidget::okButtonHandler()
{
	emit userDataSelected(userData(mListWidget->currentItem()));
}

void ListWidget::doubleClickHandler(QListWidgetItem *item)
{
	emit userDataSelected(userData(item));
}

QString ListWidget::userData(QListWidgetItem *item)
{
	return item->data(Qt::UserRole).toString();
}

void ListWidget::okActivate()
{
	mOkButton->setEnabled(true);
}
<commit_msg>Default buttons in start dialog bug fixed<commit_after>#include <QtGui/QVBoxLayout>

#include "listWidget.h"

using namespace qReal;

ListWidget::ListWidget(QWidget *parent)
	: QWidget(parent)
	, mListWidget(new QListWidget())
	, mOkButton(new QPushButton(tr("&OK")))
{
	mOkButton->setDisabled(true);

	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addWidget(mListWidget);
	mainLayout->addWidget(mOkButton);

	setLayout(mainLayout);

	connect(mListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(okActivate()));
	connect(mOkButton, SIGNAL(clicked()), this, SLOT(okButtonHandler()));
	connect(mListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*))
			, this, SLOT(doubleClickHandler(QListWidgetItem*)));
}

void ListWidget::addItem(QString const &text, QString const &userData, QString const &toolTip)
{
	QListWidgetItem *currentItem = new QListWidgetItem(text, mListWidget);
	currentItem->setData(Qt::UserRole, userData);
	currentItem->setToolTip(toolTip);
	mListWidget->addItem(currentItem);
}

void ListWidget::highlightFirstItem()
{
	if (count() == 0) {
		return;
	}
	mListWidget->setCurrentRow(0);
}

int ListWidget::count()
{
	return mListWidget->count();
}

void ListWidget::okButtonHandler()
{
	emit userDataSelected(userData(mListWidget->currentItem()));
}

void ListWidget::doubleClickHandler(QListWidgetItem *item)
{
	emit userDataSelected(userData(item));
}

QString ListWidget::userData(QListWidgetItem *item)
{
	return item->data(Qt::UserRole).toString();
}

void ListWidget::okActivate()
{
	mOkButton->setEnabled(true);
	mOkButton->setDefault(true);
}
<|endoftext|>


<commit_before>#include <boost/asio.hpp>
#include <memory>
#include <sdbusplus/asio/connection.hpp>

namespace
{

std::shared_ptr<boost::asio::io_context> ioCtx;
std::shared_ptr<sdbusplus::asio::connection> sdbusp;

} // namespace

void setIoContext(std::shared_ptr<boost::asio::io_context>& newIo)
{
    ioCtx = newIo;
}

std::shared_ptr<boost::asio::io_context> getIoContext()
{
    return ioCtx;
}

void setSdBus(std::shared_ptr<sdbusplus::asio::connection>& newBus)
{
    sdbusp = newBus;
}

std::shared_ptr<sdbusplus::asio::connection> getSdBus()
{
    return sdbusp;
}
<commit_msg>remove include boost/asio.hpp<commit_after>#include <boost/asio/io_context.hpp>
#include <memory>
#include <sdbusplus/asio/connection.hpp>

namespace
{

std::shared_ptr<boost::asio::io_context> ioCtx;
std::shared_ptr<sdbusplus::asio::connection> sdbusp;

} // namespace

void setIoContext(std::shared_ptr<boost::asio::io_context>& newIo)
{
    ioCtx = newIo;
}

std::shared_ptr<boost::asio::io_context> getIoContext()
{
    return ioCtx;
}

void setSdBus(std::shared_ptr<sdbusplus::asio::connection>& newBus)
{
    sdbusp = newBus;
}

std::shared_ptr<sdbusplus::asio::connection> getSdBus()
{
    return sdbusp;
}
<|endoftext|>


<commit_before>#include <libmemcached/common.h>

static void calc_largest_consumption(memcached_analysis_st *result,
                                     const uint32_t server_num,
                                     const uint64_t nbytes)
{
  if (result->most_used_bytes < nbytes)
  {
    result->most_used_bytes= nbytes;
    result->most_consumed_server= server_num;
  }
}

static void calc_oldest_node(memcached_analysis_st *result,
                                     const uint32_t server_num,
                                     const uint32_t uptime)
{
  if (result->longest_uptime < uptime)
  {
    result->longest_uptime= uptime;
    result->oldest_server= server_num;
  }
}

static void calc_least_free_node(memcached_analysis_st *result,
                                 const uint32_t server_num,
                                 const uint64_t max_allowed_bytes,
                                 const uint64_t used_bytes)
{
  uint64_t remaining_bytes= max_allowed_bytes - used_bytes;

  if (result->least_remaining_bytes == 0 ||
      remaining_bytes < result->least_remaining_bytes)
  {
    result->least_remaining_bytes= remaining_bytes;
    result->least_free_server= server_num;
  }
}

static void calc_average_item_size(memcached_analysis_st *result,
                                   const uint64_t total_items,
                                   const uint64_t total_bytes)
{
  if (total_items > 0 && total_bytes > 0)
  {
    result->average_item_size= (uint32_t) (total_bytes / total_items);
  }
}

static void calc_hit_ratio(memcached_analysis_st *result,
                           const uint64_t total_get_hits,
                           const uint64_t total_get_cmds)
{
  if (total_get_hits == 0 || total_get_cmds == 0)
  {
    result->pool_hit_ratio= 0;
    return;
  }

  double temp= double(total_get_hits) / total_get_cmds;
  result->pool_hit_ratio= temp * 100;
}

memcached_analysis_st *memcached_analyze(memcached_st *memc,
                                         memcached_stat_st *memc_stat,
                                         memcached_return_t *error)
{
  uint64_t total_items= 0, total_bytes= 0;
  uint64_t total_get_cmds= 0, total_get_hits= 0;

  if (memc == NULL or memc_stat == NULL)
  {
    return NULL;
  }

  memcached_return_t not_used;
  if (error == NULL)
  {
    error= &not_used;
  }

  *error= MEMCACHED_SUCCESS;
  uint32_t server_count= memcached_server_count(memc);
  memcached_analysis_st *result= (memcached_analysis_st*)libmemcached_xcalloc(memc,
                                                                              memcached_server_count(memc),
                                                                              memcached_analysis_st);

  if (result == NULL)
  {
    *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
    return NULL;
  }

  result->root= memc;

  for (uint32_t x= 0; x < server_count; x++)
  {
    calc_largest_consumption(result, x, memc_stat[x].bytes);
    calc_oldest_node(result, x, memc_stat[x].uptime);
    calc_least_free_node(result, x,
                         memc_stat[x].limit_maxbytes,
                         memc_stat[x].bytes);

    total_get_hits+= memc_stat[x].get_hits;
    total_get_cmds+= memc_stat[x].cmd_get;
    total_items+= memc_stat[x].curr_items;
    total_bytes+= memc_stat[x].bytes;
  }

  calc_average_item_size(result, total_items, total_bytes);
  calc_hit_ratio(result, total_get_hits, total_get_cmds);

  return result;
}

void memcached_analyze_free(memcached_analysis_st *ptr)
{
  libmemcached_free(ptr->root, ptr);
}
<commit_msg>Fix OSX based compile issue.<commit_after>#include <libmemcached/common.h>

static void calc_largest_consumption(memcached_analysis_st *result,
                                     const uint32_t server_num,
                                     const uint64_t nbytes)
{
  if (result->most_used_bytes < nbytes)
  {
    result->most_used_bytes= nbytes;
    result->most_consumed_server= server_num;
  }
}

static void calc_oldest_node(memcached_analysis_st *result,
                             const uint32_t server_num,
                             const uint32_t uptime)
{
  if (result->longest_uptime < uptime)
  {
    result->longest_uptime= uptime;
    result->oldest_server= server_num;
  }
}

static void calc_least_free_node(memcached_analysis_st *result,
                                 const uint32_t server_num,
                                 const uint64_t max_allowed_bytes,
                                 const uint64_t used_bytes)
{
  uint64_t remaining_bytes= max_allowed_bytes - used_bytes;

  if (result->least_remaining_bytes == 0 ||
      remaining_bytes < result->least_remaining_bytes)
  {
    result->least_remaining_bytes= remaining_bytes;
    result->least_free_server= server_num;
  }
}

static void calc_average_item_size(memcached_analysis_st *result,
                                   const uint64_t total_items,
                                   const uint64_t total_bytes)
{
  if (total_items > 0 && total_bytes > 0)
  {
    result->average_item_size= (uint32_t) (total_bytes / total_items);
  }
}

static void calc_hit_ratio(memcached_analysis_st *result,
                           const uint64_t total_get_hits,
                           const uint64_t total_get_cmds)
{
  if (total_get_hits == 0 || total_get_cmds == 0)
  {
    result->pool_hit_ratio= 0;
    return;
  }

  double temp= double(total_get_hits) / total_get_cmds;
  result->pool_hit_ratio= temp * 100;
}

memcached_analysis_st *memcached_analyze(memcached_st *memc,
                                         memcached_stat_st *memc_stat,
                                         memcached_return_t *error)
{
  uint64_t total_items= 0, total_bytes= 0;
  uint64_t total_get_cmds= 0, total_get_hits= 0;

  if (memc == NULL or memc_stat == NULL)
  {
    return NULL;
  }

  memcached_return_t not_used;
  if (error == NULL)
  {
    error= &not_used;
  }

  *error= MEMCACHED_SUCCESS;
  uint32_t server_count= memcached_server_count(memc);
  memcached_analysis_st *result= (memcached_analysis_st*)libmemcached_xcalloc(memc,
                                                                              memcached_server_count(memc),
                                                                              memcached_analysis_st);

  if (result == NULL)
  {
    *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
    return NULL;
  }

  result->root= memc;

  for (uint32_t x= 0; x < server_count; x++)
  {
    calc_largest_consumption(result, x, memc_stat[x].bytes);
    calc_oldest_node(result, x, uint32_t(memc_stat[x].uptime));
    calc_least_free_node(result, x,
                         memc_stat[x].limit_maxbytes,
                         memc_stat[x].bytes);

    total_get_hits+= memc_stat[x].get_hits;
    total_get_cmds+= memc_stat[x].cmd_get;
    total_items+= memc_stat[x].curr_items;
    total_bytes+= memc_stat[x].bytes;
  }

  calc_average_item_size(result, total_items, total_bytes);
  calc_hit_ratio(result, total_get_hits, total_get_cmds);

  return result;
}

void memcached_analyze_free(memcached_analysis_st *ptr)
{
  libmemcached_free(ptr->root, ptr);
}
<|endoftext|>


<commit_before>#include "actionlib/client/simple_action_client.h"
#include "control_msgs/FollowJointTrajectoryAction.h"
#include "control_msgs/GripperCommandAction.h"
#include "rapid_pbd/action_executor.h"
#include "rapid_pbd/action_names.h"
#include "rapid_pbd/program_executor.h"
#include "ros/ros.h"
#include "std_msgs/Bool.h"

namespace pbd = rapid::pbd;

int main(int argc, char** argv) {
  ros::init(argc, argv, "program_executor");
  ros::NodeHandle nh;
  ros::Publisher is_running_pub =
      nh.advertise<std_msgs::Bool>("is_running", 5, true);

  pbd::ActionClients action_clients;
  int num_arms;
  bool success = ros::param::get("num_arms", num_arms);
  if (!success) {
    ROS_ERROR("num_arms param must be set.");
    return 1;
  }
  while (!action_clients.head_client.waitForServer(ros::Duration(5))) {
    ROS_WARN("Waiting for head server.");
  }
  if (num_arms == 1) {
    while (!action_clients.gripper_client.waitForServer(ros::Duration(5))) {
      ROS_WARN("Waiting for gripper server.");
    }
    while (!action_clients.arm_joint_client.waitForServer(ros::Duration(5))) {
      ROS_WARN("Waiting for arm joint server.");
    }
  } else if (num_arms == 2) {
    while (!action_clients.l_gripper_client.waitForServer(ros::Duration(5))) {
      ROS_WARN("Waiting for left gripper server.");
    }
    while (!action_clients.r_gripper_client.waitForServer(ros::Duration(5))) {
      ROS_WARN("Waiting for right gripper server.");
    }
    while (!action_clients.l_arm_joint_client.waitForServer(ros::Duration(5))) {
      ROS_WARN("Waiting for left arm joint server.");
    }
    while (!action_clients.r_arm_joint_client.waitForServer(ros::Duration(5))) {
      ROS_WARN("Waiting for right arm joint server.");
    }
  } else {
    ROS_ERROR("num_arms can only be 1 or 2.");
    return 1;
  }

  rapid::pbd::ProgramExecutionServer server(rapid::pbd::kProgramActionName,
                                            is_running_pub, &action_clients);
  server.Start();
  ROS_INFO("RapidPbD program executor ready.");
  ros::spin();
  return 0;
}
<commit_msg>Added wait loop for segmentation action.<commit_after>#include "actionlib/client/simple_action_client.h"
#include "control_msgs/FollowJointTrajectoryAction.h"
#include "control_msgs/GripperCommandAction.h"
#include "rapid_pbd/action_executor.h"
#include "rapid_pbd/action_names.h"
#include "rapid_pbd/program_executor.h"
#include "ros/ros.h"
#include "std_msgs/Bool.h"

namespace pbd = rapid::pbd;

int main(int argc, char** argv) {
  ros::init(argc, argv, "program_executor");
  ros::NodeHandle nh;
  ros::Publisher is_running_pub =
      nh.advertise<std_msgs::Bool>("is_running", 5, true);

  pbd::ActionClients action_clients;
  int num_arms;
  bool success = ros::param::get("num_arms", num_arms);
  if (!success) {
    ROS_ERROR("num_arms param must be set.");
    return 1;
  }
  while (!action_clients.head_client.waitForServer(ros::Duration(5)) &&
         ros::ok()) {
    ROS_WARN("Waiting for head server.");
  }
  if (num_arms == 1) {
    while (!action_clients.gripper_client.waitForServer(ros::Duration(5)) &&
           ros::ok()) {
      ROS_WARN("Waiting for gripper server.");
    }
    while (!action_clients.arm_joint_client.waitForServer(ros::Duration(5)) &&
           ros::ok()) {
      ROS_WARN("Waiting for arm joint server.");
    }
  } else if (num_arms == 2) {
    while (!action_clients.l_gripper_client.waitForServer(ros::Duration(5)) &&
           ros::ok()) {
      ROS_WARN("Waiting for left gripper server.");
    }
    while (!action_clients.r_gripper_client.waitForServer(ros::Duration(5)) &&
           ros::ok()) {
      ROS_WARN("Waiting for right gripper server.");
    }
    while (!action_clients.l_arm_joint_client.waitForServer(ros::Duration(5)) &&
           ros::ok()) {
      ROS_WARN("Waiting for left arm joint server.");
    }
    while (!action_clients.r_arm_joint_client.waitForServer(ros::Duration(5)) &&
           ros::ok()) {
      ROS_WARN("Waiting for right arm joint server.");
    }
  } else {
    ROS_ERROR("num_arms can only be 1 or 2.");
    return 1;
  }
  while (!action_clients.surface_segmentation_client.waitForServer(
             ros::Duration(5)) &&
         ros::ok()) {
    ROS_WARN("Waiting for surface segmentation server.");
  }

  rapid::pbd::ProgramExecutionServer server(rapid::pbd::kProgramActionName,
                                            is_running_pub, &action_clients);
  server.Start();
  ROS_INFO("RapidPbD program executor ready.");
  ros::spin();
  return 0;
}
<|endoftext|>


<commit_before>#include <signal.h>
#include <unistd.h>

#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

static void signal_stop(int);

EventSystem::EventSystem(void)
: log_("/event/system"),
  queue_(),
  stop_(),
  stop_queue_(),
  timeout_queue_(),
  poll_()
{
	INFO(log_) << "Starting event system.";

	signal(SIGINT, signal_stop);
}

EventSystem::~EventSystem()
{
}

Action *
EventSystem::poll(const EventPoll::Type& type, int fd, EventCallback *cb)
{
	Action *a = poll_.poll(type, fd, cb);
	return (a);
}

Action *
EventSystem::register_interest(const EventInterest& interest, Callback *cb)
{
	switch (interest) {
	case EventInterestStop: {
		Action *a = stop_queue_.append(cb);
		return (a);
	}
	default:
		NOTREACHED();
	}
}

Action *
EventSystem::schedule(Callback *cb)
{
	Action *a = queue_.append(cb);
	return (a);
}

Action *
EventSystem::timeout(unsigned secs, Callback *cb)
{
	Action *a = timeout_queue_.append(secs, cb);
	return (a);
}

void
EventSystem::start(void)
{
	for (;;) {
		/*
		 * If we have been told to stop, fire all shutdown events.
		 */
		if (stop_ && !stop_queue_.empty()) {
			INFO(log_) << "Running stop handlers.";
			while (!stop_queue_.empty())
				stop_queue_.perform();
			INFO(log_) << "Stop handlers have been run.";
		}

		/*
		 * If there are time-triggered events whose time has come,
		 * run them.
		 */
		while (timeout_queue_.ready())
			timeout_queue_.perform();
		/*
		 * And then run a pending callback.
		 */
		queue_.perform();
		/*
		 * And if there are more pending callbacks, then do a quick
		 * poll and let them run.
		 */
		if (!queue_.empty()) {
			poll_.poll();
			continue;
		}
		/*
		 * But if there are no pending callbacks, and no timers or
		 * file descriptors being polled, stop.
		 */
		if (timeout_queue_.empty() && poll_.idle())
			break;
		/*
		 * If there are timers ticking down, then let the poll module
		 * block until a timer will be ready.
		 * XXX Maybe block 1 second less, just in case?  We'll never
		 * be a realtime system though, so any attempt at pretending
		 * to be one, beyond giving time events priority at the top of
		 * this loop, is probably a mistake.
		 */
		if (!timeout_queue_.empty()) {
			poll_.wait(timeout_queue_.interval());
			continue;
		}
		/*
		 * If, however, there's nothing sensitive to time, but someone
		 * has a file descriptor that can be blocked on, just block on it
		 * indefinitely.
		 */
		poll_.wait();
	}
}

void
EventSystem::stop(void)
{
	signal(SIGINT, SIG_DFL);
	INFO(log_) << "Stopping event system.";
	stop_ = true;
}

static void
signal_stop(int signo)
{
	ASSERT(signo == SIGINT);
	EventSystem::instance()->stop();
}
<commit_msg>Add a note about the gratuitous polling we do, especially since we're not edge-triggered.<commit_after>#include <signal.h>
#include <unistd.h>

#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

static void signal_stop(int);

EventSystem::EventSystem(void)
: log_("/event/system"),
  queue_(),
  stop_(),
  stop_queue_(),
  timeout_queue_(),
  poll_()
{
	INFO(log_) << "Starting event system.";

	signal(SIGINT, signal_stop);
}

EventSystem::~EventSystem()
{
}

Action *
EventSystem::poll(const EventPoll::Type& type, int fd, EventCallback *cb)
{
	Action *a = poll_.poll(type, fd, cb);
	return (a);
}

Action *
EventSystem::register_interest(const EventInterest& interest, Callback *cb)
{
	switch (interest) {
	case EventInterestStop: {
		Action *a = stop_queue_.append(cb);
		return (a);
	}
	default:
		NOTREACHED();
	}
}

Action *
EventSystem::schedule(Callback *cb)
{
	Action *a = queue_.append(cb);
	return (a);
}

Action *
EventSystem::timeout(unsigned secs, Callback *cb)
{
	Action *a = timeout_queue_.append(secs, cb);
	return (a);
}

void
EventSystem::start(void)
{
	for (;;) {
		/*
		 * If we have been told to stop, fire all shutdown events.
		 */
		if (stop_ && !stop_queue_.empty()) {
			INFO(log_) << "Running stop handlers.";
			while (!stop_queue_.empty())
				stop_queue_.perform();
			INFO(log_) << "Stop handlers have been run.";
		}

		/*
		 * If there are time-triggered events whose time has come,
		 * run them.
		 */
		while (timeout_queue_.ready())
			timeout_queue_.perform();
		/*
		 * And then run a pending callback.
		 */
		queue_.perform();
		/*
		 * And if there are more pending callbacks, then do a quick
		 * poll and let them run.
		 *
		 * XXX
		 * There is actually no point in polling here.  If there are
		 * more queued Callbacks, any events fired by polling will be
		 * put after them.  We should take everything off the queue,
		 * drain that (with an eye on the clock) and then poll.  We can
		 * not just wait for the queue to be empty since it might never
		 * be.
		 */
		if (!queue_.empty()) {
			poll_.poll();
			continue;
		}
		/*
		 * But if there are no pending callbacks, and no timers or
		 * file descriptors being polled, stop.
		 */
		if (timeout_queue_.empty() && poll_.idle())
			break;
		/*
		 * If there are timers ticking down, then let the poll module
		 * block until a timer will be ready.
		 * XXX Maybe block 1 second less, just in case?  We'll never
		 * be a realtime system though, so any attempt at pretending
		 * to be one, beyond giving time events priority at the top of
		 * this loop, is probably a mistake.
		 */
		if (!timeout_queue_.empty()) {
			poll_.wait(timeout_queue_.interval());
			continue;
		}
		/*
		 * If, however, there's nothing sensitive to time, but someone
		 * has a file descriptor that can be blocked on, just block on it
		 * indefinitely.
		 */
		poll_.wait();
	}
}

void
EventSystem::stop(void)
{
	signal(SIGINT, SIG_DFL);
	INFO(log_) << "Stopping event system.";
	stop_ = true;
}

static void
signal_stop(int signo)
{
	ASSERT(signo == SIGINT);
	EventSystem::instance()->stop();
}
<|endoftext|>