<commit_before>#define DEBUG 1
/**
 * File    : B.cpp
 * Author  : Kazune Takahashi
 * Created : 3/21/2020, 10:21:50 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{2LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

class Solve
{
  int N;
  vector<int> V;
  bool zero_two;
  mint ans;

public:
  Solve(int N, vector<int> V) : N{N}, V{V}
  {
    zero_two_init();
    two_zero_conv();
    calc_ans();
    flush();
  }

private:
  void flush()
  {
    if (zero_two && ans == 1)
    {
      cout << 2 << endl;
    }
    else
    {
      cout << ans << endl;
    }
  }

  void two_zero_conv()
  {
    for (auto i = 0; i < N; ++i)
    {
      if (V[i] == 2)
      {
        V[i] = 0;
      }
    }
#if DEBUG == 1
    for (auto x : V)
    {
      cerr << x;
    }
    cerr << endl;
#endif
  }

  void calc_ans()
  {
    combination C;
    ans = 0;
    for (auto i = 0; i < N; ++i)
    {
      ans += C((N - 1) % MOD, i % MOD) * V[i];
    }
  }

  void zero_two_init()
  {
    zero_two = true;
    for (auto i = 0; i < N; ++i)
    {
      if (V[i] == 1)
      {
        zero_two = false;
        break;
      }
    }
    if (zero_two)
    {
      for (auto i = 0; i < N; ++i)
      {
        if (V[i] == 2)
        {
          V[i] = 1;
        }
      }
    }
  }
};

int main()
{
  int N;
  cin >> N;
  vector<int> A(N);
  string S;
  cin >> S;
  for (auto i = 0; i < N; ++i)
  {
    A[i] = S[i] - '0';
    A[i]--;
  }
  Solve solve(N, A);
}
<commit_msg>submit B.cpp to 'B - 123 Triangle' (agc043) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : B.cpp
 * Author  : Kazune Takahashi
 * Created : 3/21/2020, 10:21:50 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{998244353LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

class Solve
{
  int N;
  vector<int> V;
  bool zero_two;
  mint ans;

public:
  Solve(int N, vector<int> V) : N{N}, V{V}
  {
    zero_two_init();
    two_zero_conv();
    calc_ans();
    flush();
  }

private:
  void flush()
  {
    if (zero_two && ans.x % 2 == 1)
    {
      cout << 2 << endl;
    }
    else
    {
      cout << ans.x % 2 << endl;
    }
  }

  void two_zero_conv()
  {
    for (auto i = 0; i < N; ++i)
    {
      if (V[i] == 2)
      {
        V[i] = 0;
      }
    }
#if DEBUG == 1
    for (auto x : V)
    {
      cerr << x;
    }
    cerr << endl;
#endif
  }

  void calc_ans()
  {
    combination C;
    ans = 0;
    for (auto i = 0; i < N; ++i)
    {
      ans += C(N - 1, i) * V[i];
    }
  }

  void zero_two_init()
  {
    zero_two = true;
    for (auto i = 0; i < N; ++i)
    {
      if (V[i] == 1)
      {
        zero_two = false;
        break;
      }
    }
    if (zero_two)
    {
      for (auto i = 0; i < N; ++i)
      {
        if (V[i] == 2)
        {
          V[i] = 1;
        }
      }
    }
  }
};

int main()
{
  int N;
  cin >> N;
  vector<int> A(N);
  string S;
  cin >> S;
  for (auto i = 0; i < N; ++i)
  {
    A[i] = S[i] - '0';
    A[i]--;
  }
  Solve solve(N, A);
}
<|endoftext|>


<commit_before>#include "ovassvep_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <openvibe/ov_directories.h>

#include "ovassvepCApplication.h"
#include "GenericStimulator/ovassvepCGenericStimulatorApplication.h"
#include "Impact/ovassvepCImpactApplication.h"

using namespace OpenViBE;

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

	if (argc < 2)
	{
		printf("Usage : %s <application-type> [application-subtype]\n", argv[0]);
		exit(1);
	}

	// initialize the OpenViBE kernel

	OpenViBE::CKernelLoader l_oKernelLoader;
	OpenViBE::CString l_sError;
	OpenViBE::Kernel::IKernelDesc* l_poKernelDesc = NULL;
	OpenViBE::Kernel::IKernelContext* l_poKernelContext = NULL;
	OpenViBE::Kernel::ILogManager* l_poLogManager = NULL;
	OpenViBE::Kernel::IConfigurationManager* l_poConfigurationManager = NULL;

	CString l_sApplicationString = CString(argv[1]);
	CString l_sScenarioFolder = CString(argv[2]);

	CString l_sApplicationType, l_sApplicationSubtype;

	if (l_sApplicationString == CString("generic"))
	{
		l_sApplicationType = "generic";
		l_sApplicationSubtype = "";
	}
	else if (l_sApplicationString == CString("impact-trainer"))
	{
		l_sApplicationType = "impact";
		l_sApplicationSubtype = "trainer";
	}
	else if (l_sApplicationString == CString("impact-shooter"))
	{
		l_sApplicationType = "impact";
		l_sApplicationSubtype = "shooter";
	}

#ifdef OVA_OS_Windows
	std::cout << "[  INF  ] Loading Windows kernel\n";
	if(!l_oKernelLoader.load(OpenViBE::Directories::getBinDir() + "/openvibe-kernel.dll", &l_sError))
#else
	std::cout << "[  INF  ] Loading Linux kernel\n";
	if(!l_oKernelLoader.load(OpenViBE::Directories::getLibDir() + "/libopenvibe-kernel.so", &l_sError))
#endif
	{
		std::cout << "[ FAILED ] Error loading kernel (" << l_sError << ")" << "\n";
	}
	else
	{
		std::cout<< "[  INF  ] Kernel module loaded, trying to get kernel descriptor\n";

		l_oKernelLoader.initialize();
		l_oKernelLoader.getKernelDesc(l_poKernelDesc);

		if(!l_poKernelDesc)
		{
			std::cout << "[ FAILED ] No kernel descriptor\n";
		}
		else
		{
			std::cout << "[  INF  ] Got kernel descriptor, trying to create kernel\n";

			l_poKernelContext = l_poKernelDesc->createKernel("ssvep-stimulator", OpenViBE::Directories::getDataDir() + "/kernel/openvibe.conf");

			if(!l_poKernelContext)
			{
				std::cout << "[ FAILED ] No kernel created by kernel descriptor\n";
			}
			else
			{
				OpenViBEToolkit::initialize(*l_poKernelContext);

				l_poConfigurationManager = &(l_poKernelContext->getConfigurationManager());
				l_poConfigurationManager->addConfigurationFromFile(l_poConfigurationManager->expand("${Path_Data}/kernel/openvibe.conf"));
				/*
				l_poConfigurationManager->createConfigurationToken("SSVEP_ApplicationDescriptor", CString(argv[1]));
				(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Info << "Application Descriptor : " << argv[1] << "\n";
				*/
				/*
				l_poConfigurationManager->createConfigurationToken("SSVEP_ApplicationDescriptor", l_sApplicationType);
				l_poConfigurationManager->createConfigurationToken("SSVEP_ApplicationSubtype", l_sApplicationSubtype);
				*/
				l_poLogManager = &(l_poKernelContext->getLogManager());

				(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Info << l_poConfigurationManager->expand("${UserHome}") << "\n";
				l_poConfigurationManager->addConfigurationFromFile(l_sScenarioFolder + "/appconf/application-configuration.conf");

				l_poConfigurationManager->createConfigurationToken("SSVEP_MindShooterFolderName", "ssvep-mind-shooter");
			}
		}
	}

	OpenViBESSVEP::CApplication* app = NULL;

	if (l_sApplicationType == CString("generic"))
	{
		(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Debug << "+ app = new OpenViBESSVEP::CGenericStimulatorApplication(...)\n";
		app = new OpenViBESSVEP::CGenericStimulatorApplication(l_sScenarioFolder);
	}
	else if (l_sApplicationType == CString("impact"))
	{
		(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Debug << "+ app = new OpenViBESSVEP::CImpactApplication(...)\n";
		(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Info << "application subtype " << l_sApplicationSubtype << "\n";
		app = new OpenViBESSVEP::CImpactApplication(l_sScenarioFolder, l_sApplicationSubtype);
	}
	else
	{
		(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Error << "Wrong application identifier specified\n";

		return 1;
	}

	app->setup(l_poKernelContext);

	app->go();

	(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Debug << "- app\n";
	delete app;

	return 0;
}

<commit_msg>fixed kernel loading<commit_after>#include "ovassvep_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <openvibe/ov_directories.h>

#include "ovassvepCApplication.h"
#include "GenericStimulator/ovassvepCGenericStimulatorApplication.h"
#include "Impact/ovassvepCImpactApplication.h"

using namespace OpenViBE;

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

	if (argc < 2)
	{
		printf("Usage : %s <application-type> [application-subtype]\n", argv[0]);
		exit(1);
	}

	// initialize the OpenViBE kernel

	OpenViBE::CKernelLoader l_oKernelLoader;
	OpenViBE::CString l_sError;
	OpenViBE::Kernel::IKernelDesc* l_poKernelDesc = NULL;
	OpenViBE::Kernel::IKernelContext* l_poKernelContext = NULL;
	OpenViBE::Kernel::ILogManager* l_poLogManager = NULL;
	OpenViBE::Kernel::IConfigurationManager* l_poConfigurationManager = NULL;

	CString l_sApplicationString = CString(argv[1]);
	CString l_sScenarioFolder = CString(argv[2]);

	CString l_sApplicationType, l_sApplicationSubtype;

	if (l_sApplicationString == CString("generic"))
	{
		l_sApplicationType = "generic";
		l_sApplicationSubtype = "";
	}
	else if (l_sApplicationString == CString("impact-trainer"))
	{
		l_sApplicationType = "impact";
		l_sApplicationSubtype = "trainer";
	}
	else if (l_sApplicationString == CString("impact-shooter"))
	{
		l_sApplicationType = "impact";
		l_sApplicationSubtype = "shooter";
	}

#ifdef TARGET_OS_Windows
	std::cout << "[  INF  ] Loading Windows kernel\n";
	if(!l_oKernelLoader.load(OpenViBE::Directories::getBinDir() + "/openvibe-kernel.dll", &l_sError))
#else
	std::cout << "[  INF  ] Loading Linux kernel\n";
	if(!l_oKernelLoader.load(OpenViBE::Directories::getLibDir() + "/libopenvibe-kernel.so", &l_sError))
#endif
	{
		std::cout << "[ FAILED ] Error loading kernel (" << l_sError << ")" << "\n";
	}
	else
	{
		std::cout<< "[  INF  ] Kernel module loaded, trying to get kernel descriptor\n";

		l_oKernelLoader.initialize();
		l_oKernelLoader.getKernelDesc(l_poKernelDesc);

		if(!l_poKernelDesc)
		{
			std::cout << "[ FAILED ] No kernel descriptor\n";
		}
		else
		{
			std::cout << "[  INF  ] Got kernel descriptor, trying to create kernel\n";

			l_poKernelContext = l_poKernelDesc->createKernel("ssvep-stimulator", OpenViBE::Directories::getDataDir() + "/kernel/openvibe.conf");

			if(!l_poKernelContext)
			{
				std::cout << "[ FAILED ] No kernel created by kernel descriptor\n";
			}
			else
			{
				OpenViBEToolkit::initialize(*l_poKernelContext);

				l_poConfigurationManager = &(l_poKernelContext->getConfigurationManager());
				l_poConfigurationManager->addConfigurationFromFile(l_poConfigurationManager->expand("${Path_Data}/kernel/openvibe.conf"));
				/*
				l_poConfigurationManager->createConfigurationToken("SSVEP_ApplicationDescriptor", CString(argv[1]));
				(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Info << "Application Descriptor : " << argv[1] << "\n";
				*/
				/*
				l_poConfigurationManager->createConfigurationToken("SSVEP_ApplicationDescriptor", l_sApplicationType);
				l_poConfigurationManager->createConfigurationToken("SSVEP_ApplicationSubtype", l_sApplicationSubtype);
				*/
				l_poLogManager = &(l_poKernelContext->getLogManager());

				(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Info << l_poConfigurationManager->expand("${UserHome}") << "\n";
				l_poConfigurationManager->addConfigurationFromFile(l_sScenarioFolder + "/appconf/application-configuration.conf");

				l_poConfigurationManager->createConfigurationToken("SSVEP_MindShooterFolderName", "ssvep-mind-shooter");
			}
		}
	}

	OpenViBESSVEP::CApplication* app = NULL;

	if (l_sApplicationType == CString("generic"))
	{
		(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Debug << "+ app = new OpenViBESSVEP::CGenericStimulatorApplication(...)\n";
		app = new OpenViBESSVEP::CGenericStimulatorApplication(l_sScenarioFolder);
	}
	else if (l_sApplicationType == CString("impact"))
	{
		(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Debug << "+ app = new OpenViBESSVEP::CImpactApplication(...)\n";
		(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Info << "application subtype " << l_sApplicationSubtype << "\n";
		app = new OpenViBESSVEP::CImpactApplication(l_sScenarioFolder, l_sApplicationSubtype);
	}
	else
	{
		(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Error << "Wrong application identifier specified\n";

		return 1;
	}

	app->setup(l_poKernelContext);

	app->go();

	(*l_poLogManager) << OpenViBE::Kernel::LogLevel_Debug << "- app\n";
	delete app;

	return 0;
}

<|endoftext|>


<commit_before>#include "profilerui.h"
#include "ui_profilerui.h"
#include <qpainter.h>
#include <qpixmap.h>

static const int MAX_FRAMES = 200;

ProfileModel::Block::Block()
{
	m_frames.reserve(MAX_FRAMES);
	for(int i = 0; i < MAX_FRAMES; ++i)
	{
		m_frames.push_back(0);
	}
	m_hit_counts.reserve(MAX_FRAMES);
	for (int i = 0; i < MAX_FRAMES; ++i)
	{
		m_hit_counts.push_back(0);
	}
}

ProfileModel::ProfileModel(QWidget* parent)
	: QAbstractItemModel(parent)
{
	Lumix::g_profiler.getFrameListeners().bind<ProfileModel, &ProfileModel::onFrame>(this);
	m_root = NULL;
	m_frame = -1;
}

void ProfileModel::cloneBlock(Block* my_block, Lumix::Profiler::Block* remote_block)
{
	ASSERT(my_block->m_name == remote_block->m_name);
	my_block->m_frames.push_back(remote_block->getLength());
	my_block->m_hit_counts.push_back(remote_block->getHitCount());
	if (my_block->m_frames.size() > MAX_FRAMES)
	{
		my_block->m_frames.pop_front();
	}
	if (my_block->m_hit_counts.size() > MAX_FRAMES)
	{
		my_block->m_hit_counts.pop_front();
	}

	if (!my_block->m_first_child && remote_block->m_first_child)
	{
		Lumix::Profiler::Block* remote_child = remote_block->m_first_child;
		Block* my_child = new Block;
		my_child->m_function = remote_child->m_function;
		my_child->m_name = remote_child->m_name;
		my_child->m_parent = my_block;
		my_child->m_next = NULL;
		my_child->m_first_child = NULL;
		my_block->m_first_child = my_child;
		cloneBlock(my_child, remote_child);
	}
	else if(my_block->m_first_child)
	{
		Lumix::Profiler::Block* remote_child = remote_block->m_first_child;
		Block* my_child = my_block->m_first_child;
		if(my_child->m_function != remote_child->m_function || my_child->m_name != remote_child->m_name)
		{
			Block* my_new_child = new Block;
			my_new_child->m_function = remote_child->m_function;
			my_new_child->m_name = remote_child->m_name;
			my_new_child->m_parent = my_block;
			my_new_child->m_next = my_child;
			my_new_child->m_first_child = NULL;
			my_block->m_first_child = my_new_child;
			my_child = my_new_child;
		}
		cloneBlock(my_child, remote_child);
	}

	if (!my_block->m_next && remote_block->m_next)
	{
		Lumix::Profiler::Block* remote_next = remote_block->m_next;
		Block* my_next = new Block;
		my_next->m_function = remote_next->m_function;
		my_next->m_name = remote_next->m_name;
		my_next->m_parent = my_block->m_parent;
		my_next->m_next = NULL;
		my_next->m_first_child = NULL;
		my_block->m_next = my_next;
		cloneBlock(my_next, remote_next);

	}
	else if (my_block->m_next)
	{
		if(my_block->m_next->m_function != remote_block->m_next->m_function || my_block->m_next->m_name != remote_block->m_next->m_name)
		{
			Block* my_next = new Block;
			Lumix::Profiler::Block* remote_next = remote_block->m_next;
			my_next->m_function = remote_next->m_function;
			my_next->m_name = remote_next->m_name;
			my_next->m_parent = my_block->m_parent;
			my_next->m_next = my_block->m_next;
			my_next->m_first_child = NULL;
			my_block->m_next = my_next;
		}
		cloneBlock(my_block->m_next, remote_block->m_next);
	}
}

void ProfileModel::onFrame()
{
	if(!m_root && Lumix::g_profiler.getRootBlock())
	{
		m_root = new Block;
		m_root->m_function = Lumix::g_profiler.getRootBlock()->m_function;
		m_root->m_name = Lumix::g_profiler.getRootBlock()->m_name;
		m_root->m_parent = NULL;
		m_root->m_next = NULL;
		m_root->m_first_child = NULL;
	}
	if(m_root)
	{
		cloneBlock(m_root, Lumix::g_profiler.getRootBlock());
	}
	static int hit = 0;
	++hit;
	int count = 0;
	Block* child = m_root->m_first_child;
	while(child)
	{
		++count;
		child = child->m_next;
	}
	if(hit % 10 == 0)
	{
		emit dataChanged(createIndex(0, 0, m_root), createIndex(count, 0, m_root));
	}
}

QVariant ProfileModel::headerData(int section, Qt::Orientation, int role) const
{
	if(role == Qt::DisplayRole)
	{
		switch(section)
		{
			case Values::FUNCTION:
				return "Function";
			case Values::NAME:
				return "Name";
			case Values::LENGTH:
				return "Length (ms)";
			case Values::LENGTH_EXCLUSIVE:
				return "Length exclusive (ms)";
			case Values::HIT_COUNT:
				return "Hit count";
				break;
			default:
				ASSERT(false);
				return QVariant();
		}
	}
	return QVariant();
}

QModelIndex ProfileModel::index(int row, int column, const QModelIndex& parent) const
{
	if(!hasIndex(row, column, parent))
	{
		return QModelIndex();
	}
	Block* block = NULL;
	if(parent.internalPointer() != NULL)
	{
		block = static_cast<Block*>(parent.internalPointer())->m_first_child;
	}
	else
	{
		block = m_root;
	}

	int index = row;
	while (block && index > 0)
	{
		block = block->m_next;
		--index;
	}

	return createIndex(row, column, block);
}

QModelIndex ProfileModel::parent(const QModelIndex& index) const
{
	if (!index.isValid() || !index.internalPointer())
	{
		return QModelIndex();
	}

	Block* child = static_cast<Block*>(index.internalPointer());
	Block* parent = child->m_parent;

	if (parent == NULL)
	{
		return QModelIndex();
	}

	int row = 0;
	Block* row_sibling = parent->m_first_child;
	while(row_sibling && row_sibling != child)
	{
		row_sibling = row_sibling->m_next;
		++row;
	}
	ASSERT(row_sibling);
	return createIndex(row, 0, parent);
}

int ProfileModel::rowCount(const QModelIndex& parent_index) const
{
	Block* parent;
	if (parent_index.column() > 0 || Lumix::g_profiler.getRootBlock() == NULL)
		return 0;

	if (!parent_index.isValid() || !parent_index.internalPointer())
	{
		int count = 0;
		Block* root = m_root;
		while (root)
		{
			++count;
			root = root->m_next;
		}
		return count;
	}
	else
	{
		parent = static_cast<Block*>(parent_index.internalPointer());
	}

	int count = 0;
	Block* child = parent->m_first_child;
	while(child)
	{
		++count;
		child = child->m_next;
	}
	return count;
}

int ProfileModel::columnCount(const QModelIndex&) const
{
	return (int)Values::COUNT;
}

QVariant ProfileModel::data(const QModelIndex& index, int role) const
{
	if (!index.isValid() || !index.internalPointer())
	{
		return QVariant();
	}

	if (role != Qt::DisplayRole)
	{
		return QVariant();
	}
	Block* block = static_cast<Block*>(index.internalPointer());
	switch(index.column())
	{
		case Values::FUNCTION:
			return block->m_function;
		case Values::NAME:
			return block->m_name;
		case Values::LENGTH:
			return m_frame >= 0 && m_frame < block->m_frames.size() ? block->m_frames[m_frame] : (block->m_frames.isEmpty() ? 0 : block->m_frames.back());
		case Values::LENGTH_EXCLUSIVE:
			{
				if (m_frame >= 0 && m_frame < block->m_frames.size())
				{
					float length = block->m_frames[m_frame];
					Block* child = block->m_first_child;
					while (child)
					{
						length -= m_frame < child->m_frames.size() ? child->m_frames[m_frame] : (child->m_frames.isEmpty() ? 0 : child->m_frames.back());
						child = child->m_next;
					}
					return length;
				}
				else
				{
					float length = block->m_frames.isEmpty() ? 0 : block->m_frames.back();
					Block* child = block->m_first_child;
					while (child)
					{
						length -= child->m_frames.isEmpty() ? 0 : child->m_frames.back();
						child = child->m_next;
					}
					return length;
				}
			}
			break;
		case Values::HIT_COUNT:
			return m_frame >= 0 && m_frame < block->m_hit_counts.size() ? block->m_hit_counts[m_frame] : (block->m_hit_counts.isEmpty() ? 0 : block->m_hit_counts.back());
			break;
		default:
			ASSERT(false);
			return QVariant();
	}
}

ProfilerUI::ProfilerUI(QWidget* parent)
	: QDockWidget(parent)
	, m_ui(new Ui::ProfilerUI)
{
	m_sortable_model = new QSortFilterProxyModel(this);
	m_model = new ProfileModel(this);
	m_sortable_model->setSourceModel(m_model);
	m_ui->setupUi(this);
	m_ui->profileTreeView->setModel(m_sortable_model);
	m_ui->profileTreeView->header()->setSectionResizeMode(0, QHeaderView::ResizeMode::Stretch);
	m_ui->profileTreeView->header()->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents);
	m_ui->profileTreeView->header()->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents);
	connect(m_model, &QAbstractItemModel::dataChanged, this, &ProfilerUI::on_dataChanged);
	connect(m_ui->graphView, &ProfilerGraph::frameSet, this, &ProfilerUI::on_frameSet);
	m_ui->graphView->setModel(m_model);
}

void ProfilerUI::on_dataChanged()
{
	m_ui->graphView->update();
}

ProfilerUI::~ProfilerUI()
{
	delete m_ui;
}

void ProfilerUI::on_recordCheckBox_stateChanged(int)
{
	Lumix::g_profiler.toggleRecording();
	m_ui->profileTreeView->setModel(NULL);
	m_sortable_model->setSourceModel(m_model);
	m_ui->profileTreeView->setModel(m_sortable_model);
	m_ui->profileTreeView->update();
}

void ProfilerUI::on_frameSet()
{
	m_ui->recordCheckBox->setChecked(false);
	m_ui->profileTreeView->update();
	m_model->setFrame(m_ui->graphView->getFrame());
}

void ProfilerUI::on_profileTreeView_clicked(const QModelIndex &index)
{
	if(index.internalPointer() != NULL)
	{
		m_ui->graphView->setBlock(static_cast<ProfileModel::Block*>(index.internalPointer()));
		m_ui->graphView->update();
	}
}
<commit_msg>crash in the profiler ui fixed<commit_after>#include "profilerui.h"
#include "ui_profilerui.h"
#include <qpainter.h>
#include <qpixmap.h>

static const int MAX_FRAMES = 200;

ProfileModel::Block::Block()
{
	m_frames.reserve(MAX_FRAMES);
	for(int i = 0; i < MAX_FRAMES; ++i)
	{
		m_frames.push_back(0);
	}
	m_hit_counts.reserve(MAX_FRAMES);
	for (int i = 0; i < MAX_FRAMES; ++i)
	{
		m_hit_counts.push_back(0);
	}
}

ProfileModel::ProfileModel(QWidget* parent)
	: QAbstractItemModel(parent)
{
	Lumix::g_profiler.getFrameListeners().bind<ProfileModel, &ProfileModel::onFrame>(this);
	m_root = NULL;
	m_frame = -1;
}

void ProfileModel::cloneBlock(Block* my_block, Lumix::Profiler::Block* remote_block)
{
	ASSERT(my_block->m_name == remote_block->m_name);
	my_block->m_frames.push_back(remote_block->getLength());
	my_block->m_hit_counts.push_back(remote_block->getHitCount());
	if (my_block->m_frames.size() > MAX_FRAMES)
	{
		my_block->m_frames.pop_front();
	}
	if (my_block->m_hit_counts.size() > MAX_FRAMES)
	{
		my_block->m_hit_counts.pop_front();
	}

	if (!my_block->m_first_child && remote_block->m_first_child)
	{
		Lumix::Profiler::Block* remote_child = remote_block->m_first_child;
		Block* my_child = new Block;
		my_child->m_function = remote_child->m_function;
		my_child->m_name = remote_child->m_name;
		my_child->m_parent = my_block;
		my_child->m_next = NULL;
		my_child->m_first_child = NULL;
		my_block->m_first_child = my_child;
		cloneBlock(my_child, remote_child);
	}
	else if(my_block->m_first_child)
	{
		Lumix::Profiler::Block* remote_child = remote_block->m_first_child;
		Block* my_child = my_block->m_first_child;
		if(my_child->m_function != remote_child->m_function || my_child->m_name != remote_child->m_name)
		{
			Block* my_new_child = new Block;
			my_new_child->m_function = remote_child->m_function;
			my_new_child->m_name = remote_child->m_name;
			my_new_child->m_parent = my_block;
			my_new_child->m_next = my_child;
			my_new_child->m_first_child = NULL;
			my_block->m_first_child = my_new_child;
			my_child = my_new_child;
		}
		cloneBlock(my_child, remote_child);
	}

	if (!my_block->m_next && remote_block->m_next)
	{
		Lumix::Profiler::Block* remote_next = remote_block->m_next;
		Block* my_next = new Block;
		my_next->m_function = remote_next->m_function;
		my_next->m_name = remote_next->m_name;
		my_next->m_parent = my_block->m_parent;
		my_next->m_next = NULL;
		my_next->m_first_child = NULL;
		my_block->m_next = my_next;
		cloneBlock(my_next, remote_next);

	}
	else if (my_block->m_next)
	{
		if(my_block->m_next->m_function != remote_block->m_next->m_function || my_block->m_next->m_name != remote_block->m_next->m_name)
		{
			Block* my_next = new Block;
			Lumix::Profiler::Block* remote_next = remote_block->m_next;
			my_next->m_function = remote_next->m_function;
			my_next->m_name = remote_next->m_name;
			my_next->m_parent = my_block->m_parent;
			my_next->m_next = my_block->m_next;
			my_next->m_first_child = NULL;
			my_block->m_next = my_next;
		}
		cloneBlock(my_block->m_next, remote_block->m_next);
	}
}

void ProfileModel::onFrame()
{
	if(!m_root && Lumix::g_profiler.getRootBlock())
	{
		m_root = new Block;
		m_root->m_function = Lumix::g_profiler.getRootBlock()->m_function;
		m_root->m_name = Lumix::g_profiler.getRootBlock()->m_name;
		m_root->m_parent = NULL;
		m_root->m_next = NULL;
		m_root->m_first_child = NULL;
	}
	if(m_root)
	{
		cloneBlock(m_root, Lumix::g_profiler.getRootBlock());
	}
	static int hit = 0;
	++hit;
	int count = 0;
	Block* child = m_root->m_first_child;
	while(child)
	{
		++count;
		child = child->m_next;
	}
	if(hit % 10 == 0)
	{
		emit dataChanged(createIndex(0, 0, m_root), createIndex(count, 0, m_root));
	}
}

QVariant ProfileModel::headerData(int section, Qt::Orientation, int role) const
{
	if(role == Qt::DisplayRole)
	{
		switch(section)
		{
			case Values::FUNCTION:
				return "Function";
			case Values::NAME:
				return "Name";
			case Values::LENGTH:
				return "Length (ms)";
			case Values::LENGTH_EXCLUSIVE:
				return "Length exclusive (ms)";
			case Values::HIT_COUNT:
				return "Hit count";
				break;
			default:
				ASSERT(false);
				return QVariant();
		}
	}
	return QVariant();
}

QModelIndex ProfileModel::index(int row, int column, const QModelIndex& parent) const
{
	if(!hasIndex(row, column, parent))
	{
		return QModelIndex();
	}
	Block* block = NULL;
	if(parent.internalPointer() != NULL)
	{
		block = static_cast<Block*>(parent.internalPointer())->m_first_child;
	}
	else
	{
		block = m_root;
	}

	int index = row;
	while (block && index > 0)
	{
		block = block->m_next;
		--index;
	}

	return createIndex(row, column, block);
}

QModelIndex ProfileModel::parent(const QModelIndex& index) const
{
	if (!index.isValid() || !index.internalPointer())
	{
		return QModelIndex();
	}

	Block* child = static_cast<Block*>(index.internalPointer());
	Block* parent = child->m_parent;

	if (parent == NULL)
	{
		return QModelIndex();
	}

	int row = 0;
	Block* row_sibling = parent->m_first_child;
	while(row_sibling && row_sibling != child)
	{
		row_sibling = row_sibling->m_next;
		++row;
	}
	ASSERT(row_sibling);
	return createIndex(row, 0, parent);
}

int ProfileModel::rowCount(const QModelIndex& parent_index) const
{
	Block* parent;
	if (parent_index.column() > 0 || Lumix::g_profiler.getRootBlock() == NULL)
		return 0;

	if (!parent_index.isValid() || !parent_index.internalPointer())
	{
		int count = 0;
		Block* root = m_root;
		while (root)
		{
			++count;
			root = root->m_next;
		}
		return count;
	}
	else
	{
		parent = static_cast<Block*>(parent_index.internalPointer());
	}

	int count = 0;
	Block* child = parent->m_first_child;
	while(child)
	{
		++count;
		child = child->m_next;
	}
	return count;
}

int ProfileModel::columnCount(const QModelIndex&) const
{
	return (int)Values::COUNT;
}

QVariant ProfileModel::data(const QModelIndex& index, int role) const
{
	if (!index.isValid() || !index.internalPointer())
	{
		return QVariant();
	}

	if (role != Qt::DisplayRole)
	{
		return QVariant();
	}
	Block* block = static_cast<Block*>(index.internalPointer());
	switch(index.column())
	{
		case Values::FUNCTION:
			return block->m_function;
		case Values::NAME:
			return block->m_name;
		case Values::LENGTH:
			return m_frame >= 0 && m_frame < block->m_frames.size() ? block->m_frames[m_frame] : (block->m_frames.isEmpty() ? 0 : block->m_frames.back());
		case Values::LENGTH_EXCLUSIVE:
			{
				if (m_frame >= 0 && m_frame < block->m_frames.size())
				{
					float length = block->m_frames[m_frame];
					Block* child = block->m_first_child;
					while (child)
					{
						length -= m_frame < child->m_frames.size() ? child->m_frames[m_frame] : (child->m_frames.isEmpty() ? 0 : child->m_frames.back());
						child = child->m_next;
					}
					return length;
				}
				else
				{
					float length = block->m_frames.isEmpty() ? 0 : block->m_frames.back();
					Block* child = block->m_first_child;
					while (child)
					{
						length -= child->m_frames.isEmpty() ? 0 : child->m_frames.back();
						child = child->m_next;
					}
					return length;
				}
			}
			break;
		case Values::HIT_COUNT:
			return m_frame >= 0 && m_frame < block->m_hit_counts.size() ? block->m_hit_counts[m_frame] : (block->m_hit_counts.isEmpty() ? 0 : block->m_hit_counts.back());
			break;
		default:
			ASSERT(false);
			return QVariant();
	}
}

ProfilerUI::ProfilerUI(QWidget* parent)
	: QDockWidget(parent)
	, m_ui(new Ui::ProfilerUI)
{
	m_sortable_model = new QSortFilterProxyModel(this);
	m_model = new ProfileModel(this);
	m_sortable_model->setSourceModel(m_model);
	m_ui->setupUi(this);
	m_ui->profileTreeView->setModel(m_sortable_model);
	m_ui->profileTreeView->header()->setSectionResizeMode(0, QHeaderView::ResizeMode::Stretch);
	m_ui->profileTreeView->header()->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents);
	m_ui->profileTreeView->header()->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents);
	connect(m_model, &QAbstractItemModel::dataChanged, this, &ProfilerUI::on_dataChanged);
	connect(m_ui->graphView, &ProfilerGraph::frameSet, this, &ProfilerUI::on_frameSet);
	m_ui->graphView->setModel(m_model);
}

void ProfilerUI::on_dataChanged()
{
	m_ui->graphView->update();
}

ProfilerUI::~ProfilerUI()
{
	delete m_ui;
}

void ProfilerUI::on_recordCheckBox_stateChanged(int)
{
	Lumix::g_profiler.toggleRecording();
	m_ui->profileTreeView->setModel(NULL);
	m_sortable_model->setSourceModel(m_model);
	m_ui->profileTreeView->setModel(m_sortable_model);
	m_ui->profileTreeView->update();
}

void ProfilerUI::on_frameSet()
{
	m_ui->recordCheckBox->setChecked(false);
	m_ui->profileTreeView->update();
	m_model->setFrame(m_ui->graphView->getFrame());
}

void ProfilerUI::on_profileTreeView_clicked(const QModelIndex &index)
{
	if(index.internalPointer() != NULL)
	{
		m_ui->graphView->setBlock(static_cast<ProfileModel::Block*>(m_sortable_model->mapToSource(index).internalPointer()));
		m_ui->graphView->update();
	}
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (testabilitydriver@nokia.com)
**
** This file is part of Testability Driver Qt Agent
**
** If you have questions regarding the use of this file, please contact
** Nokia at testabilitydriver@nokia.com .
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QtPlugin>
#include <QDebug>

#include <testabilityutils.h>
#include <taslogger.h>
#include "scenegraphtraverse.h"

#include <QQuickItem>
#include <QQuickView>
#include <QQmlContext>
#include <QQmlEngine>

/*!
    \class SceneGraphTraverse
    \brief SceneGraphTraverse traverse QWidgets and QGraphicsItems

    Traverse the basic qt ui elements
*/

/*!
    Constructor
*/
SceneGraphTraverse::SceneGraphTraverse(QObject* parent)
    : QObject(parent)
{
    mTraverseUtils = new TasTraverseUtils();
}

/*!
    Destructor
*/
SceneGraphTraverse::~SceneGraphTraverse()
{
    delete mTraverseUtils;
}

void SceneGraphTraverse::beginTraverse(TasCommand* command)
{
    mTraverseUtils->createFilter(command);
}

void SceneGraphTraverse::endTraverse()
{
    mTraverseUtils->clearFilter();
}

/*!
  Traverse QGraphicsItem based objects.
 */
void SceneGraphTraverse::traverseGraphicsItem(TasObject* objectInfo, QGraphicsItem* graphicsItem, TasCommand* command)
{
    Q_UNUSED(objectInfo);
    Q_UNUSED(graphicsItem);
    Q_UNUSED(command);
}

/*!
  Traverse QObject based items.
*/
void SceneGraphTraverse::traverseObject(TasObject* objectInfo, QObject* object, TasCommand* command)
{
    Q_UNUSED(command);

    QQuickItem* item = qobject_cast<QQuickItem*>(object);

    if (item) {
        QQmlContext* context = QQmlEngine::contextForObject(object);

        if (context) {
            QString name = context->nameForObject(object);
            objectInfo->addAttribute("QML_ID", name);
        }

        mTraverseUtils->addObjectDetails(objectInfo, object);

        objectInfo->addAttribute("objectType", TYPE_QSCENEGRAPH);

        QPointF point = item->mapToScene(QPoint());

        objectInfo->addAttribute("x", point.x());
        objectInfo->addAttribute("y", point.y());
        objectInfo->addAttribute("x_absolute", point.x());
        objectInfo->addAttribute("y_absolute", point.y());

        objectInfo->addAttribute("x_relative", item->x());
        objectInfo->addAttribute("y_relative", item->y());

        // TODO already included?
        objectInfo->addAttribute("width", item->width());
        objectInfo->addAttribute("height", item->height());
    }
}

<commit_msg>Fixed problem with visualizer not being capable of handling fractional coordinates<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (testabilitydriver@nokia.com)
**
** This file is part of Testability Driver Qt Agent
**
** If you have questions regarding the use of this file, please contact
** Nokia at testabilitydriver@nokia.com .
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QtPlugin>
#include <QDebug>

#include <testabilityutils.h>
#include <taslogger.h>
#include "scenegraphtraverse.h"

#include <QQuickItem>
#include <QQuickView>
#include <QQmlContext>
#include <QQmlEngine>

/*!
    \class SceneGraphTraverse
    \brief SceneGraphTraverse traverse QWidgets and QGraphicsItems

    Traverse the basic qt ui elements
*/

/*!
    Constructor
*/
SceneGraphTraverse::SceneGraphTraverse(QObject* parent)
    : QObject(parent)
{
    mTraverseUtils = new TasTraverseUtils();
}

/*!
    Destructor
*/
SceneGraphTraverse::~SceneGraphTraverse()
{
    delete mTraverseUtils;
}

void SceneGraphTraverse::beginTraverse(TasCommand* command)
{
    mTraverseUtils->createFilter(command);
}

void SceneGraphTraverse::endTraverse()
{
    mTraverseUtils->clearFilter();
}

/*!
  Traverse QGraphicsItem based objects.
 */
void SceneGraphTraverse::traverseGraphicsItem(TasObject* objectInfo, QGraphicsItem* graphicsItem, TasCommand* command)
{
    Q_UNUSED(objectInfo);
    Q_UNUSED(graphicsItem);
    Q_UNUSED(command);
}

/*!
  Traverse QObject based items.
*/
void SceneGraphTraverse::traverseObject(TasObject* objectInfo, QObject* object, TasCommand* command)
{
    Q_UNUSED(command);

    QQuickItem* item = qobject_cast<QQuickItem*>(object);

    if (item) {
        QQmlContext* context = QQmlEngine::contextForObject(object);

        if (context) {
            QString name = context->nameForObject(object);
            objectInfo->addAttribute("QML_ID", name);
        }

        mTraverseUtils->addObjectDetails(objectInfo, object);

        objectInfo->addAttribute("objectType", TYPE_QSCENEGRAPH);

        QPointF point = item->mapToScene(QPoint());

        // needed for visualizer
        objectInfo->addAttribute("x", (int)point.x());
        objectInfo->addAttribute("y", (int)point.y());
        objectInfo->addAttribute("x_absolute", (int)point.x());
        objectInfo->addAttribute("y_absolute", (int)point.y());

        objectInfo->addAttribute("x_relative", item->x());
        objectInfo->addAttribute("y_relative", item->y());

        // TODO already included?
        objectInfo->addAttribute("width", item->width());
        objectInfo->addAttribute("height", item->height());
    }
}

<|endoftext|>


<commit_before>#include "Application.h"

#include "Module.h"
#include "ModuleScripting.h"
#include "ModuleAudio.h"
#include "ModuleCamera3D.h"
#include "ModuleFileSystem.h"
#include "ModuleGOManager.h"
#include "ModuleInput.h"
#include "ModuleSceneIntro.h"
#include "ModuleLighting.h"
#include "ModulePhysics3D.h"
#include "ModuleRenderer3D.h"
#include "ModuleResourceManager.h"
#include "ModuleEditor.h"
#include "ModuleWindow.h"

#include "Time.h"
#include "Random.h"
#include "EventQueue.h"
#include "Data.h"

#include "Brofiler/include/Brofiler.h"

#include "ComponentCar.h"

using namespace std;

Application::Application()
{
	// Time controller
	time = new Time();

	// Random
	rnd = new Random();

	// EventQueue
	event_queue = new EventQueue();

	// Modules
	window = new ModuleWindow("window");
	resource_manager = new ModuleResourceManager("resource_manager");
	input = new ModuleInput("input");
	audio = new ModuleAudio("audio");
	scene_intro = new ModuleSceneIntro("scene_intro");
	renderer3D = new ModuleRenderer3D("renderer");
	camera = new ModuleCamera3D("camera");
	physics = new ModulePhysics3D("physics");
	scripting = new ModuleScripting("scripting");
	editor = new ModuleEditor("editor");
	file_system = new ModuleFileSystem("file_system");
	go_manager = new ModuleGOManager("go_manager");
	lighting = new ModuleLighting("lighting");

	//Globals
	g_Debug = new DebugDraw("debug_draw");

	// Modules will Init() Start() and Update in this order
	// They will CleanUp() in reverse order

	// Main Modules
	AddModule(file_system);
	AddModule(resource_manager);
	AddModule(window);
	AddModule(input);
	AddModule(g_Debug);
	AddModule(audio);
	AddModule(scripting);
	AddModule(physics);
	AddModule(go_manager);
	AddModule(camera);
	AddModule(lighting);

	// Scenes
	AddModule(scene_intro);

	//Editor
	AddModule(editor);

	// Renderer last!
	AddModule(renderer3D);
}

Application::~Application()
{
	delete rnd;
	delete event_queue;

	vector<Module*>::reverse_iterator i = list_modules.rbegin();

	while (i != list_modules.rend())
	{
		delete (*i);
		++i;
	}

	delete time;
}

bool Application::Init()
{
	bool ret = true;

	//Load Configuration
	char* buffer = nullptr;
	if (App->file_system->Load("Configuration.json", &buffer) == 0)
	{
		LOG("Error while loading Configuration file");
		//Create a new Configuration file
		if (buffer)
			delete[] buffer;

		Data root_node;
		root_node.AppendBool("start_in_game", false);
		vector<Module*>::reverse_iterator i = list_modules.rbegin();

		while (i != list_modules.rend())
		{
			root_node.AppendJObject((*i)->GetName());
			++i;
		}

		size_t size = root_node.Serialize(&buffer);
		App->file_system->Save("Configuration.json", buffer, size);
	}
	Data config(buffer);
	delete[] buffer;

	// Game is initialized in PlayMode?
	if (config.GetBool("start_in_game"))
	{
		start_in_game = true;
		game_state = GAME_RUNNING;
	}

	// Call Init() in all modules
	vector<Module*>::iterator i = list_modules.begin();

	while (i != list_modules.end() && ret == true)
	{
		ret = (*i)->Init(config.GetJObject((*i)->GetName()));
		++i;
	}

	// After all Init calls we call Start() in all modules
	LOG("Application Start --------------");
	i = list_modules.begin();

	while(i != list_modules.end() && ret == true)
	{
		ret = (*i)->Start();
		++i;
	}

	capped_ms = 1000 / max_fps;

	//// Play all Components of every GameObject on the scene
	if (start_in_game)
	{
		time->Play();

		for (std::vector<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); it++)
			(*it)->OnPlay();
	}

	return ret;
}

// ---------------------------------------------
void Application::PrepareUpdate()
{
	time->UpdateFrame();
}

// ---------------------------------------------
void Application::FinishUpdate()
{
	event_queue->ProcessEvents();
	if (want_to_load == true)
	{
		want_to_load = false;
		resource_manager->LoadSceneFromAssets(scene_to_load);
	}
}

void Application::LoadScene(const char* path)
{
	if (want_to_load == false)
	{
		scene_to_load = (char*)path;
		want_to_load = true;
	}
}

void Application::OnStop()
{
	for (std::vector<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); it++)
	{
		(*it)->OnStop();
	}
}

void Application::OnPlay()
{
	for (std::vector<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); it++)
		(*it)->OnPlay();
}

void Application::RunGame()
{
	//Save current scene only if the game was stopped
	if (game_state == GAME_STOP)
		go_manager->SaveSceneBeforeRunning();

	game_state = GAME_RUNNING;
	time->Play();

	OnPlay();
}

void Application::PauseGame()
{
	game_state = GAME_PAUSED;
	time->Pause();

	for (std::vector<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); it++)
	{
		(*it)->OnPause();
	}
}

void Application::StopGame()
{
	game_state = GAME_STOP;
	OnStop();
	go_manager->LoadSceneBeforeRunning();
	time->Stop();
}

// Call PreUpdate, Update and PostUpdate on all modules
update_status Application::Update()
{
	BROFILER_FRAME("GameLoop")

	update_status ret = UPDATE_CONTINUE;
	PrepareUpdate();

	vector<Module*>::iterator i = list_modules.begin();

	while (i != list_modules.end() && ret == UPDATE_CONTINUE)
	{
		ret = (*i)->PreUpdate();
		++i;
	}

	i = list_modules.begin();

	while(i != list_modules.end() && ret == UPDATE_CONTINUE)
	{
		ret = (*i)->Update();
		++i;
	}

	i = list_modules.begin();

	while (i != list_modules.end() && ret == UPDATE_CONTINUE)
	{
		ret = (*i)->PostUpdate();
		i++;
	}

	FinishUpdate();
	return ret;
}

bool Application::CleanUp()
{
	bool ret = true;

	vector<Module*>::reverse_iterator i = list_modules.rbegin();

	while (i != list_modules.rend() && ret == true)
	{
		ret = (*i)->CleanUp();
		++i;
	}

	return ret;
}

void Application::SaveBeforeClosing()
{
	Data root_node;
	char* buf;

	root_node.AppendBool("start_in_game", start_in_game);

	vector<Module*>::reverse_iterator i = list_modules.rbegin();

	while (i != list_modules.rend())
	{
		(*i)->SaveBeforeClosing(root_node.AppendJObject((*i)->GetName()));
		++i;
	}

	size_t size = root_node.Serialize(&buf);
	uint success = App->file_system->Save("Configuration.json", buf, size);

	if (success == 0)
		LOG("Configuration could not be saved before closing");

	delete[] buf;
}

void Application::AddModule(Module* mod)
{
	list_modules.push_back(mod);
}

void Application::OpenURL(const char* url)
{
	ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
}

void Application::SetMaxFPS(int max_fps)
{
	this->max_fps = max_fps;
	if (max_fps == 0) this->max_fps = -1;
	capped_ms = 1000 / max_fps;
}

int Application::GetFPS()
{
	return 60; //TODO: Update time with fps limit.
}

bool Application::ChangeGameState(GameStates new_state)
{
	bool success = false;
	switch (new_state)
	{
	case GAME_STOP:
		if (game_state == GAME_RUNNING || game_state == GAME_PAUSED)
		{
			StopGame();
			success = true;
		}
		break;
	case GAME_RUNNING:
		if (game_state == GAME_STOP || game_state == GAME_PAUSED)
		{
			RunGame();
			success = true;
		}
		break;
	case GAME_PAUSED:
		if (game_state == GAME_RUNNING || game_state == GAME_NEXT_FRAME)
		{
			PauseGame();
			success = true;
		}
		break;
	case GAME_NEXT_FRAME:
		if(game_state == GAME_RUNNING || game_state == GAME_PAUSED) //TODO: Now this features is not available yet. Nothing happens in the game now.
			//NextFrameGame();
		break;
	}

	return success;
}

///Returns true if the game simulation has started. If the game is paused also returns true.
bool Application::IsGameRunning() const
{
	return (game_state == GAME_RUNNING || game_state == GAME_NEXT_FRAME || game_state == GAME_PAUSED) ? true : false;
}

///Returns true if the game is paused or in next frame mode. If the game is stop returns false.
bool Application::IsGamePaused() const
{
	return (game_state == GAME_PAUSED || game_state == GAME_NEXT_FRAME) ? true : false;
}

bool Application::StartInGame() const
{
	return start_in_game;
}
<commit_msg>Not saving configuration if startInGame == true<commit_after>#include "Application.h"

#include "Module.h"
#include "ModuleScripting.h"
#include "ModuleAudio.h"
#include "ModuleCamera3D.h"
#include "ModuleFileSystem.h"
#include "ModuleGOManager.h"
#include "ModuleInput.h"
#include "ModuleSceneIntro.h"
#include "ModuleLighting.h"
#include "ModulePhysics3D.h"
#include "ModuleRenderer3D.h"
#include "ModuleResourceManager.h"
#include "ModuleEditor.h"
#include "ModuleWindow.h"

#include "Time.h"
#include "Random.h"
#include "EventQueue.h"
#include "Data.h"

#include "Brofiler/include/Brofiler.h"

#include "ComponentCar.h"

using namespace std;

Application::Application()
{
	// Time controller
	time = new Time();

	// Random
	rnd = new Random();

	// EventQueue
	event_queue = new EventQueue();

	// Modules
	window = new ModuleWindow("window");
	resource_manager = new ModuleResourceManager("resource_manager");
	input = new ModuleInput("input");
	audio = new ModuleAudio("audio");
	scene_intro = new ModuleSceneIntro("scene_intro");
	renderer3D = new ModuleRenderer3D("renderer");
	camera = new ModuleCamera3D("camera");
	physics = new ModulePhysics3D("physics");
	scripting = new ModuleScripting("scripting");
	editor = new ModuleEditor("editor");
	file_system = new ModuleFileSystem("file_system");
	go_manager = new ModuleGOManager("go_manager");
	lighting = new ModuleLighting("lighting");

	//Globals
	g_Debug = new DebugDraw("debug_draw");

	// Modules will Init() Start() and Update in this order
	// They will CleanUp() in reverse order

	// Main Modules
	AddModule(file_system);
	AddModule(resource_manager);
	AddModule(window);
	AddModule(input);
	AddModule(g_Debug);
	AddModule(audio);
	AddModule(scripting);
	AddModule(physics);
	AddModule(go_manager);
	AddModule(camera);
	AddModule(lighting);

	// Scenes
	AddModule(scene_intro);

	//Editor
	AddModule(editor);

	// Renderer last!
	AddModule(renderer3D);
}

Application::~Application()
{
	delete rnd;
	delete event_queue;

	vector<Module*>::reverse_iterator i = list_modules.rbegin();

	while (i != list_modules.rend())
	{
		delete (*i);
		++i;
	}

	delete time;
}

bool Application::Init()
{
	bool ret = true;

	//Load Configuration
	char* buffer = nullptr;
	if (App->file_system->Load("Configuration.json", &buffer) == 0)
	{
		LOG("Error while loading Configuration file");
		//Create a new Configuration file
		if (buffer)
			delete[] buffer;

		Data root_node;
		root_node.AppendBool("start_in_game", false);
		vector<Module*>::reverse_iterator i = list_modules.rbegin();

		while (i != list_modules.rend())
		{
			root_node.AppendJObject((*i)->GetName());
			++i;
		}
	if (App->StartInGame() == false)
		{
			size_t size = root_node.Serialize(&buffer);
			App->file_system->Save("Configuration.json", buffer, size);
		}
	}
	Data config(buffer);
	delete[] buffer;

	// Game is initialized in PlayMode?
	if (config.GetBool("start_in_game"))
	{
		start_in_game = true;
		game_state = GAME_RUNNING;
	}

	// Call Init() in all modules
	vector<Module*>::iterator i = list_modules.begin();

	while (i != list_modules.end() && ret == true)
	{
		ret = (*i)->Init(config.GetJObject((*i)->GetName()));
		++i;
	}

	// After all Init calls we call Start() in all modules
	LOG("Application Start --------------");
	i = list_modules.begin();

	while(i != list_modules.end() && ret == true)
	{
		ret = (*i)->Start();
		++i;
	}

	capped_ms = 1000 / max_fps;

	//// Play all Components of every GameObject on the scene
	if (start_in_game)
	{
		time->Play();

		for (std::vector<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); it++)
			(*it)->OnPlay();
	}

	return ret;
}

// ---------------------------------------------
void Application::PrepareUpdate()
{
	time->UpdateFrame();
}

// ---------------------------------------------
void Application::FinishUpdate()
{
	event_queue->ProcessEvents();
	if (want_to_load == true)
	{
		want_to_load = false;
		resource_manager->LoadSceneFromAssets(scene_to_load);
	}
}

void Application::LoadScene(const char* path)
{
	if (want_to_load == false)
	{
		scene_to_load = (char*)path;
		want_to_load = true;
	}
}

void Application::OnStop()
{
	for (std::vector<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); it++)
	{
		(*it)->OnStop();
	}
}

void Application::OnPlay()
{
	for (std::vector<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); it++)
		(*it)->OnPlay();
}

void Application::RunGame()
{
	//Save current scene only if the game was stopped
	if (game_state == GAME_STOP)
		go_manager->SaveSceneBeforeRunning();

	game_state = GAME_RUNNING;
	time->Play();

	OnPlay();
}

void Application::PauseGame()
{
	game_state = GAME_PAUSED;
	time->Pause();

	for (std::vector<Module*>::iterator it = list_modules.begin(); it != list_modules.end(); it++)
	{
		(*it)->OnPause();
	}
}

void Application::StopGame()
{
	game_state = GAME_STOP;
	OnStop();
	go_manager->LoadSceneBeforeRunning();
	time->Stop();
}

// Call PreUpdate, Update and PostUpdate on all modules
update_status Application::Update()
{
	BROFILER_FRAME("GameLoop")

	update_status ret = UPDATE_CONTINUE;
	PrepareUpdate();

	vector<Module*>::iterator i = list_modules.begin();

	while (i != list_modules.end() && ret == UPDATE_CONTINUE)
	{
		ret = (*i)->PreUpdate();
		++i;
	}

	i = list_modules.begin();

	while(i != list_modules.end() && ret == UPDATE_CONTINUE)
	{
		ret = (*i)->Update();
		++i;
	}

	i = list_modules.begin();

	while (i != list_modules.end() && ret == UPDATE_CONTINUE)
	{
		ret = (*i)->PostUpdate();
		i++;
	}

	FinishUpdate();
	return ret;
}

bool Application::CleanUp()
{
	bool ret = true;

	vector<Module*>::reverse_iterator i = list_modules.rbegin();

	while (i != list_modules.rend() && ret == true)
	{
		ret = (*i)->CleanUp();
		++i;
	}

	return ret;
}

void Application::SaveBeforeClosing()
{
	Data root_node;
	char* buf;

	root_node.AppendBool("start_in_game", start_in_game);

	vector<Module*>::reverse_iterator i = list_modules.rbegin();

	while (i != list_modules.rend())
	{
		(*i)->SaveBeforeClosing(root_node.AppendJObject((*i)->GetName()));
		++i;
	}

	size_t size = root_node.Serialize(&buf);
	if (App->StartInGame() == false)
	{
		uint success = App->file_system->Save("Configuration.json", buf, size);
	}

	if (success == 0)
		LOG("Configuration could not be saved before closing");

	delete[] buf;
}

void Application::AddModule(Module* mod)
{
	list_modules.push_back(mod);
}

void Application::OpenURL(const char* url)
{
	ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
}

void Application::SetMaxFPS(int max_fps)
{
	this->max_fps = max_fps;
	if (max_fps == 0) this->max_fps = -1;
	capped_ms = 1000 / max_fps;
}

int Application::GetFPS()
{
	return 60; //TODO: Update time with fps limit.
}

bool Application::ChangeGameState(GameStates new_state)
{
	bool success = false;
	switch (new_state)
	{
	case GAME_STOP:
		if (game_state == GAME_RUNNING || game_state == GAME_PAUSED)
		{
			StopGame();
			success = true;
		}
		break;
	case GAME_RUNNING:
		if (game_state == GAME_STOP || game_state == GAME_PAUSED)
		{
			RunGame();
			success = true;
		}
		break;
	case GAME_PAUSED:
		if (game_state == GAME_RUNNING || game_state == GAME_NEXT_FRAME)
		{
			PauseGame();
			success = true;
		}
		break;
	case GAME_NEXT_FRAME:
		if(game_state == GAME_RUNNING || game_state == GAME_PAUSED) //TODO: Now this features is not available yet. Nothing happens in the game now.
			//NextFrameGame();
		break;
	}

	return success;
}

///Returns true if the game simulation has started. If the game is paused also returns true.
bool Application::IsGameRunning() const
{
	return (game_state == GAME_RUNNING || game_state == GAME_NEXT_FRAME || game_state == GAME_PAUSED) ? true : false;
}

///Returns true if the game is paused or in next frame mode. If the game is stop returns false.
bool Application::IsGamePaused() const
{
	return (game_state == GAME_PAUSED || game_state == GAME_NEXT_FRAME) ? true : false;
}

bool Application::StartInGame() const
{
	return start_in_game;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, RangerUFO
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of ranger_bhvr_tree nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef RANGER_BHVR_TREE_AGENT_PROXY_HPP
#define	RANGER_BHVR_TREE_AGENT_PROXY_HPP

#include <mutex>
#include <map>

namespace ranger { namespace bhvr_tree {

template <class AgentProxy>
class decorator_counter_node;

namespace detail {

template <class Mutex, class AgentProxy>
class agent_proxy_base {
public:
	agent_proxy_base() = default;

	agent_proxy_base(const agent_proxy_base<Mutex, AgentProxy>&) = delete;
	agent_proxy_base<Mutex, AgentProxy>& operator = (const agent_proxy_base<Mutex, AgentProxy>&) = delete;

	bool less_then_increase(const decorator_counter_node<AgentProxy>* key, size_t value) {
		std::lock_guard<Mutex> lock(m_counters_mtx);

		auto it = m_counters.emplace(key, 0).first;
		if (it->second >= value) {
			return false;
		}

		++it->second;
		return true;
	}

	void clear_all_state() {
		std::lock_guard<Mutex> lock(m_counters_mtx);
		m_counters.clear();
	}

private:
	std::map<const decorator_counter_node<AgentProxy>*, size_t> m_counters;
	Mutex m_counters_mtx;
};

}

template <class Agent, class Mutex = std::mutex>
class agent_proxy : public detail::agent_proxy_base<Mutex, agent_proxy<Agent, Mutex>> {
public:
	using agent_type = Agent;
	using mutex_type = Mutex;

	agent_proxy(Agent& agent) : m_agent(agent) {
		// nop
	}

	Agent& get_agent() const {
		return m_agent;
	}

	Agent* operator -> () const {
		return &m_agent;
	}

private:
	Agent& m_agent;
};

template <class Mutex>
class agent_proxy<void, Mutex> : public detail::agent_proxy_base<Mutex, agent_proxy<void, Mutex>> {
public:
	using agent_type = void;
	using mutex_type = Mutex;
};

// An optional policy for agent_proxy.
struct dummy_mutex {
	void lock() {
		// nop
	}

	bool try_lock() {
		return true;
	}

	void unlock() {
		// nop
	}
};

} }

#endif	// RANGER_BHVR_TREE_AGENT_PROXY_HPP
<commit_msg>为`agent_proxy`增加`Clock Policy`<commit_after>// Copyright (c) 2015, RangerUFO
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of ranger_bhvr_tree nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef RANGER_BHVR_TREE_AGENT_PROXY_HPP
#define	RANGER_BHVR_TREE_AGENT_PROXY_HPP

#include <mutex>
#include <chrono>
#include <map>

namespace ranger { namespace bhvr_tree {

template <class AgentProxy>
class decorator_counter_node;

namespace detail {

template <class Mutex, class Clock, class AgentProxy>
class agent_proxy_base {
public:
	agent_proxy_base() = default;

	agent_proxy_base(const agent_proxy_base<Mutex, Clock, AgentProxy>&) = delete;
	agent_proxy_base<Mutex, Clock, AgentProxy>& operator = (const agent_proxy_base<Mutex, Clock, AgentProxy>&) = delete;

	bool less_then_increase(const decorator_counter_node<AgentProxy>* key, size_t value) {
		std::lock_guard<Mutex> lock(m_counters_mtx);

		auto it = m_counters.emplace(key, 0).first;
		if (it->second >= value) {
			return false;
		}

		++it->second;
		return true;
	}

	void clear_all_state() {
		std::lock_guard<Mutex> lock(m_counters_mtx);
		m_counters.clear();
	}

private:
	std::map<const decorator_counter_node<AgentProxy>*, size_t> m_counters;
	Mutex m_counters_mtx;
};

}

template <class Agent, class Mutex = std::mutex, class Clock = std::chrono::high_resolution_clock>
class agent_proxy : public detail::agent_proxy_base<Mutex, Clock, agent_proxy<Agent, Mutex, Clock>> {
public:
	using agent_type = Agent;
	using mutex_type = Mutex;
	using clock_type = Clock;

	agent_proxy(Agent& agent) : m_agent(agent) {
		// nop
	}

	Agent& get_agent() const {
		return m_agent;
	}

	Agent* operator -> () const {
		return &m_agent;
	}

private:
	Agent& m_agent;
};

template <class Mutex, class Clock>
class agent_proxy<void, Mutex, Clock> : public detail::agent_proxy_base<Mutex, Clock, agent_proxy<void, Mutex, Clock>> {
public:
	using agent_type = void;
	using mutex_type = Mutex;
	using clock_type = Clock;
};

// An optional policy for agent_proxy.
struct dummy_mutex {
	void lock() {
		// nop
	}

	bool try_lock() {
		return true;
	}

	void unlock() {
		// nop
	}
};

} }

#endif	// RANGER_BHVR_TREE_AGENT_PROXY_HPP
<|endoftext|>


<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/native/aw_autofill_manager_delegate.h"

#include "android_webview/browser/aw_browser_context.h"
#include "android_webview/browser/aw_content_browser_client.h"
#include "android_webview/browser/aw_pref_store.h"
#include "android_webview/native/aw_contents.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/logging.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/pref_service_builder.h"
#include "components/autofill/content/browser/autocheckout/whitelist_manager.h"
#include "components/autofill/core/browser/autofill_popup_delegate.h"
#include "components/autofill/core/common/autofill_pref_names.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "jni/AwAutofillManagerDelegate_jni.h"

using base::android::AttachCurrentThread;
using base::android::ConvertUTF16ToJavaString;
using base::android::ScopedJavaLocalRef;
using content::WebContents;

DEFINE_WEB_CONTENTS_USER_DATA_KEY(android_webview::AwAutofillManagerDelegate);

namespace android_webview {

// Ownership: The native object is created (if autofill enabled) and owned by
// AwContents. The native object creates the java peer which handles most
// autofill functionality at the java side. The java peer is owned by Java
// AwContents. The native object only maintains a weak ref to it.
AwAutofillManagerDelegate::AwAutofillManagerDelegate(WebContents* contents)
    : web_contents_(contents),
      save_form_data_(false) {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> delegate;
  delegate.Reset(
      Java_AwAutofillManagerDelegate_create(env, reinterpret_cast<jint>(this)));

  AwContents* aw_contents = AwContents::FromWebContents(web_contents_);
  aw_contents->SetAwAutofillManagerDelegate(delegate.obj());
  java_ref_ = JavaObjectWeakGlobalRef(env, delegate.obj());
}

AwAutofillManagerDelegate::~AwAutofillManagerDelegate() {
  HideAutofillPopup();
}

void AwAutofillManagerDelegate::SetSaveFormData(bool enabled) {
  save_form_data_ = enabled;
}

bool AwAutofillManagerDelegate::GetSaveFormData() {
  return save_form_data_;
}

PrefService* AwAutofillManagerDelegate::GetPrefs() {
  return user_prefs::UserPrefs::Get(
      AwContentBrowserClient::GetAwBrowserContext());
}

autofill::PersonalDataManager*
AwAutofillManagerDelegate::GetPersonalDataManager() {
  return NULL;
}

autofill::autocheckout::WhitelistManager*
AwAutofillManagerDelegate::GetAutocheckoutWhitelistManager() const {
  return NULL;
}

void AwAutofillManagerDelegate::ShowAutofillPopup(
    const gfx::RectF& element_bounds,
    base::i18n::TextDirection text_direction,
    const std::vector<string16>& values,
    const std::vector<string16>& labels,
    const std::vector<string16>& icons,
    const std::vector<int>& identifiers,
    base::WeakPtr<autofill::AutofillPopupDelegate> delegate) {

  values_ = values;
  identifiers_ = identifiers;
  delegate_ = delegate;

  // Convert element_bounds to be in screen space.
  gfx::Rect client_area;
  web_contents_->GetView()->GetContainerBounds(&client_area);
  gfx::RectF element_bounds_in_screen_space =
      element_bounds + client_area.OffsetFromOrigin();

  ShowAutofillPopupImpl(element_bounds_in_screen_space,
                        values,
                        labels,
                        identifiers);
}

void AwAutofillManagerDelegate::ShowAutofillPopupImpl(
    const gfx::RectF& element_bounds,
    const std::vector<string16>& values,
    const std::vector<string16>& labels,
    const std::vector<int>& identifiers) {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
  if (obj.is_null())
    return;

  // We need an array of AutofillSuggestion.
  size_t count = values.size();

  ScopedJavaLocalRef<jobjectArray> data_array =
      Java_AwAutofillManagerDelegate_createAutofillSuggestionArray(env, count);

  for (size_t i = 0; i < count; ++i) {
    ScopedJavaLocalRef<jstring> name = ConvertUTF16ToJavaString(env, values[i]);
    ScopedJavaLocalRef<jstring> label =
        ConvertUTF16ToJavaString(env, labels[i]);
    Java_AwAutofillManagerDelegate_addToAutofillSuggestionArray(
        env,
        data_array.obj(),
        i,
        name.obj(),
        label.obj(),
        identifiers[i]);
  }

  Java_AwAutofillManagerDelegate_showAutofillPopup(
      env,
      obj.obj(),
      element_bounds.x(),
      element_bounds.y(), element_bounds.width(),
      element_bounds.height(), data_array.obj());
}

void AwAutofillManagerDelegate::UpdateAutofillPopupDataListValues(
    const std::vector<base::string16>& values,
    const std::vector<base::string16>& labels) {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::HideAutofillPopup() {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
  if (obj.is_null())
    return;
  delegate_.reset();
  Java_AwAutofillManagerDelegate_hideAutofillPopup(env, obj.obj());
}

bool AwAutofillManagerDelegate::IsAutocompleteEnabled() {
  return GetSaveFormData();
}

void AwAutofillManagerDelegate::SuggestionSelected(JNIEnv* env,
                                                   jobject object,
                                                   jint position) {
  if (delegate_)
    delegate_->DidAcceptSuggestion(values_[position], identifiers_[position]);
}

void AwAutofillManagerDelegate::HideRequestAutocompleteDialog() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::OnAutocheckoutError() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::OnAutocheckoutSuccess() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::ShowAutofillSettings() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::ConfirmSaveCreditCard(
    const autofill::AutofillMetrics& metric_logger,
    const autofill::CreditCard& credit_card,
    const base::Closure& save_card_callback) {
  NOTIMPLEMENTED();
}

bool AwAutofillManagerDelegate::ShowAutocheckoutBubble(
    const gfx::RectF& bounding_box,
    bool is_google_user,
    const base::Callback<void(autofill::AutocheckoutBubbleState)>& callback) {
  NOTIMPLEMENTED();
  return false;
}

void AwAutofillManagerDelegate::HideAutocheckoutBubble() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::ShowRequestAutocompleteDialog(
    const autofill::FormData& form,
    const GURL& source_url,
    autofill::DialogType dialog_type,
    const base::Callback<void(const autofill::FormStructure*,
                              const std::string&)>& callback) {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::AddAutocheckoutStep(
    autofill::AutocheckoutStepType step_type) {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::UpdateAutocheckoutStep(
    autofill::AutocheckoutStepType step_type,
    autofill::AutocheckoutStepStatus step_status) {
  NOTIMPLEMENTED();
}

bool RegisterAwAutofillManagerDelegate(JNIEnv* env) {
  return RegisterNativesImpl(env) >= 0;
}

} // namespace android_webview
<commit_msg>am 2c3943e4: Merge "Prevent log spam in autofill" into klp-dev<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/native/aw_autofill_manager_delegate.h"

#include "android_webview/browser/aw_browser_context.h"
#include "android_webview/browser/aw_content_browser_client.h"
#include "android_webview/browser/aw_pref_store.h"
#include "android_webview/native/aw_contents.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/logging.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/pref_service_builder.h"
#include "components/autofill/content/browser/autocheckout/whitelist_manager.h"
#include "components/autofill/core/browser/autofill_popup_delegate.h"
#include "components/autofill/core/common/autofill_pref_names.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "jni/AwAutofillManagerDelegate_jni.h"

using base::android::AttachCurrentThread;
using base::android::ConvertUTF16ToJavaString;
using base::android::ScopedJavaLocalRef;
using content::WebContents;

DEFINE_WEB_CONTENTS_USER_DATA_KEY(android_webview::AwAutofillManagerDelegate);

namespace android_webview {

// Ownership: The native object is created (if autofill enabled) and owned by
// AwContents. The native object creates the java peer which handles most
// autofill functionality at the java side. The java peer is owned by Java
// AwContents. The native object only maintains a weak ref to it.
AwAutofillManagerDelegate::AwAutofillManagerDelegate(WebContents* contents)
    : web_contents_(contents),
      save_form_data_(false) {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> delegate;
  delegate.Reset(
      Java_AwAutofillManagerDelegate_create(env, reinterpret_cast<jint>(this)));

  AwContents* aw_contents = AwContents::FromWebContents(web_contents_);
  aw_contents->SetAwAutofillManagerDelegate(delegate.obj());
  java_ref_ = JavaObjectWeakGlobalRef(env, delegate.obj());
}

AwAutofillManagerDelegate::~AwAutofillManagerDelegate() {
  HideAutofillPopup();
}

void AwAutofillManagerDelegate::SetSaveFormData(bool enabled) {
  save_form_data_ = enabled;
}

bool AwAutofillManagerDelegate::GetSaveFormData() {
  return save_form_data_;
}

PrefService* AwAutofillManagerDelegate::GetPrefs() {
  return user_prefs::UserPrefs::Get(
      AwContentBrowserClient::GetAwBrowserContext());
}

autofill::PersonalDataManager*
AwAutofillManagerDelegate::GetPersonalDataManager() {
  return NULL;
}

autofill::autocheckout::WhitelistManager*
AwAutofillManagerDelegate::GetAutocheckoutWhitelistManager() const {
  return NULL;
}

void AwAutofillManagerDelegate::ShowAutofillPopup(
    const gfx::RectF& element_bounds,
    base::i18n::TextDirection text_direction,
    const std::vector<string16>& values,
    const std::vector<string16>& labels,
    const std::vector<string16>& icons,
    const std::vector<int>& identifiers,
    base::WeakPtr<autofill::AutofillPopupDelegate> delegate) {

  values_ = values;
  identifiers_ = identifiers;
  delegate_ = delegate;

  // Convert element_bounds to be in screen space.
  gfx::Rect client_area;
  web_contents_->GetView()->GetContainerBounds(&client_area);
  gfx::RectF element_bounds_in_screen_space =
      element_bounds + client_area.OffsetFromOrigin();

  ShowAutofillPopupImpl(element_bounds_in_screen_space,
                        values,
                        labels,
                        identifiers);
}

void AwAutofillManagerDelegate::ShowAutofillPopupImpl(
    const gfx::RectF& element_bounds,
    const std::vector<string16>& values,
    const std::vector<string16>& labels,
    const std::vector<int>& identifiers) {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
  if (obj.is_null())
    return;

  // We need an array of AutofillSuggestion.
  size_t count = values.size();

  ScopedJavaLocalRef<jobjectArray> data_array =
      Java_AwAutofillManagerDelegate_createAutofillSuggestionArray(env, count);

  for (size_t i = 0; i < count; ++i) {
    ScopedJavaLocalRef<jstring> name = ConvertUTF16ToJavaString(env, values[i]);
    ScopedJavaLocalRef<jstring> label =
        ConvertUTF16ToJavaString(env, labels[i]);
    Java_AwAutofillManagerDelegate_addToAutofillSuggestionArray(
        env,
        data_array.obj(),
        i,
        name.obj(),
        label.obj(),
        identifiers[i]);
  }

  Java_AwAutofillManagerDelegate_showAutofillPopup(
      env,
      obj.obj(),
      element_bounds.x(),
      element_bounds.y(), element_bounds.width(),
      element_bounds.height(), data_array.obj());
}

void AwAutofillManagerDelegate::UpdateAutofillPopupDataListValues(
    const std::vector<base::string16>& values,
    const std::vector<base::string16>& labels) {
  // Leaving as an empty method since updating autofill popup window
  // dynamically does not seem to be a useful feature for android webview.
  // See crrev.com/18102002 if need to implement.
}

void AwAutofillManagerDelegate::HideAutofillPopup() {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
  if (obj.is_null())
    return;
  delegate_.reset();
  Java_AwAutofillManagerDelegate_hideAutofillPopup(env, obj.obj());
}

bool AwAutofillManagerDelegate::IsAutocompleteEnabled() {
  return GetSaveFormData();
}

void AwAutofillManagerDelegate::SuggestionSelected(JNIEnv* env,
                                                   jobject object,
                                                   jint position) {
  if (delegate_)
    delegate_->DidAcceptSuggestion(values_[position], identifiers_[position]);
}

void AwAutofillManagerDelegate::HideRequestAutocompleteDialog() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::OnAutocheckoutError() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::OnAutocheckoutSuccess() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::ShowAutofillSettings() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::ConfirmSaveCreditCard(
    const autofill::AutofillMetrics& metric_logger,
    const autofill::CreditCard& credit_card,
    const base::Closure& save_card_callback) {
  NOTIMPLEMENTED();
}

bool AwAutofillManagerDelegate::ShowAutocheckoutBubble(
    const gfx::RectF& bounding_box,
    bool is_google_user,
    const base::Callback<void(autofill::AutocheckoutBubbleState)>& callback) {
  NOTIMPLEMENTED();
  return false;
}

void AwAutofillManagerDelegate::HideAutocheckoutBubble() {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::ShowRequestAutocompleteDialog(
    const autofill::FormData& form,
    const GURL& source_url,
    autofill::DialogType dialog_type,
    const base::Callback<void(const autofill::FormStructure*,
                              const std::string&)>& callback) {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::AddAutocheckoutStep(
    autofill::AutocheckoutStepType step_type) {
  NOTIMPLEMENTED();
}

void AwAutofillManagerDelegate::UpdateAutocheckoutStep(
    autofill::AutocheckoutStepType step_type,
    autofill::AutocheckoutStepStatus step_status) {
  NOTIMPLEMENTED();
}

bool RegisterAwAutofillManagerDelegate(JNIEnv* env) {
  return RegisterNativesImpl(env) >= 0;
}

} // namespace android_webview
<|endoftext|>


<commit_before>#include <algorithm>
#include "application_manager/app_launch/apps_launcher.h"
#include "utils/make_shared.h"
#include "utils/timer_task_impl.h"
#include <iostream>

namespace app_launch {
struct LauncherGenerator {
  LauncherGenerator(AppsLauncher& apps_laucnher,
                    connection_handler::ConnectionHandler& connection_handler,
                    const uint16_t app_launch_max_retry_attempt,
                    const uint16_t app_launch_retry_wait_time)
      : apps_laucnher_(apps_laucnher)
      , connection_handler_(connection_handler)
      , app_launch_max_retry_attempt_(app_launch_max_retry_attempt)
      , app_launch_retry_wait_time_(app_launch_retry_wait_time) {}
  AppsLauncher::LauncherPtr operator()() {
    return utils::MakeShared<AppsLauncher::Launcher>(
        apps_laucnher_,
        connection_handler_,
        app_launch_max_retry_attempt_,
        app_launch_retry_wait_time_);
  }

  AppsLauncher& apps_laucnher_;
  connection_handler::ConnectionHandler& connection_handler_;
  const uint16_t app_launch_max_retry_attempt_;
  const uint16_t app_launch_retry_wait_time_;
};

CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch")
AppsLauncher::AppsLauncher(
    connection_handler::ConnectionHandler& connection_handler,
    const uint16_t max_number_of_ios_device,
    const uint16_t app_launch_max_retry_attempt,
    const uint16_t app_launch_retry_wait_time) {
  sync_primitives::AutoLock lock(launchers_lock_);
  free_launchers_.resize(max_number_of_ios_device);
  std::generate(free_launchers_.begin(),
                free_launchers_.end(),
                LauncherGenerator(*this,
                                  connection_handler,
                                  app_launch_max_retry_attempt,
                                  app_launch_retry_wait_time));
}

void AppsLauncher::StartLaunching(ApplicationDataPtr app_data) {
  LOG4CXX_AUTO_TRACE(logger_);
  sync_primitives::AutoLock lock(launchers_lock_);
  DCHECK_OR_RETURN_VOID(!free_launchers_.empty())
  const AppLaunchers::iterator it = free_launchers_.begin();
  LauncherPtr app_launcher = *it;
  works_launchers_.push_back(app_launcher);
  free_launchers_.erase(it);
  app_launcher->PosponedLaunch(app_data);
}

struct AppLauncherFinder {
  AppLauncherFinder(const ApplicationDataPtr& app_data) : app_data_(app_data) {}
  bool operator()(const AppsLauncher::LauncherPtr& launcher) const {
    DCHECK_OR_RETURN(launcher->app_data_ && app_data_, false)
    return *launcher->app_data_ == *app_data_;
  }
  const ApplicationDataPtr& app_data_;
};

void AppsLauncher::StopLaunching(ApplicationDataPtr app_data) {
  sync_primitives::AutoLock lock(launchers_lock_);
  const AppLaunchers::iterator it = std::find_if(works_launchers_.begin(),
                                                 works_launchers_.end(),
                                                 AppLauncherFinder(app_data));
  if (it != works_launchers_.end()) {
    LauncherPtr launcher = *it;
    launcher->Clear();
    free_launchers_.push_back(launcher);
    works_launchers_.erase(it);
  } else {
    LOG4CXX_DEBUG(logger_,
                  "Unable to StopLaunching" << app_data->mobile_app_id_);
  }
}

void AppsLauncher::OnLaunched(ApplicationDataPtr app_data) {
  LOG4CXX_AUTO_TRACE(logger_);
  StopLaunching(app_data);
}

void AppsLauncher::OnRetryAttemptsExhausted(ApplicationDataPtr app_data) {
  LOG4CXX_AUTO_TRACE(logger_);
  StopLaunching(app_data);
}

AppsLauncher::Launcher::Launcher(
    AppsLauncher& parent,
    connection_handler::ConnectionHandler& connection_handler,
    const uint16_t app_launch_max_retry_attempt,
    const uint16_t app_launch_retry_wait_time)
    : retry_timer_(
          "AppsLauncherTimer",
          new timer::TimerTaskImpl<Launcher>(this, &Launcher::LaunchNow))
    , app_launch_max_retry_attempt_(app_launch_max_retry_attempt)
    , app_launch_retry_wait_time_(app_launch_retry_wait_time)
    , connection_handler_(connection_handler)
    , parent_(parent) {}

void AppsLauncher::Launcher::PosponedLaunch(
    const app_launch::ApplicationDataPtr& app_data) {
  DCHECK(!app_data_);
  app_data_ = app_data;
  retry_index_ = 0;
  retry_timer_.Start(app_launch_retry_wait_time_, timer::kPeriodic);
  LOG4CXX_DEBUG(logger_,
                "Applicaiton " << app_data->mobile_app_id_ << " on device "
                               << app_data->device_mac_
                               << " will be launched in "
                               << app_launch_retry_wait_time_ << " ms");
}

void AppsLauncher::Launcher::Clear() {
  retry_timer_.Stop();
  app_data_.reset();
  retry_index_ = 0;
}

void AppsLauncher::Launcher::LaunchNow() {
  if (retry_index_++ < app_launch_max_retry_attempt_) {
    LOG4CXX_DEBUG(logger_,
                  "Run App " << app_data_->mobile_app_id_ << "with bundle "
                             << app_data_->bundle_id_ << " On Device "
                             << app_data_->device_mac_);

    connection_handler_.RunAppOnDevice(app_data_->device_mac_,
                                       app_data_->bundle_id_);
  } else {
    parent_.OnRetryAttemptsExhausted(app_data_);
  }
}

}  // namespace app_launch
<commit_msg>Fix for coverity issue 170762<commit_after>#include <algorithm>
#include "application_manager/app_launch/apps_launcher.h"
#include "utils/make_shared.h"
#include "utils/timer_task_impl.h"
#include <iostream>

namespace app_launch {
struct LauncherGenerator {
  LauncherGenerator(AppsLauncher& apps_laucnher,
                    connection_handler::ConnectionHandler& connection_handler,
                    const uint16_t app_launch_max_retry_attempt,
                    const uint16_t app_launch_retry_wait_time)
      : apps_laucnher_(apps_laucnher)
      , connection_handler_(connection_handler)
      , app_launch_max_retry_attempt_(app_launch_max_retry_attempt)
      , app_launch_retry_wait_time_(app_launch_retry_wait_time) {}
  AppsLauncher::LauncherPtr operator()() {
    return utils::MakeShared<AppsLauncher::Launcher>(
        apps_laucnher_,
        connection_handler_,
        app_launch_max_retry_attempt_,
        app_launch_retry_wait_time_);
  }

  AppsLauncher& apps_laucnher_;
  connection_handler::ConnectionHandler& connection_handler_;
  const uint16_t app_launch_max_retry_attempt_;
  const uint16_t app_launch_retry_wait_time_;
};

CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch")
AppsLauncher::AppsLauncher(
    connection_handler::ConnectionHandler& connection_handler,
    const uint16_t max_number_of_ios_device,
    const uint16_t app_launch_max_retry_attempt,
    const uint16_t app_launch_retry_wait_time) {
  sync_primitives::AutoLock lock(launchers_lock_);
  free_launchers_.resize(max_number_of_ios_device);
  std::generate(free_launchers_.begin(),
                free_launchers_.end(),
                LauncherGenerator(*this,
                                  connection_handler,
                                  app_launch_max_retry_attempt,
                                  app_launch_retry_wait_time));
}

void AppsLauncher::StartLaunching(ApplicationDataPtr app_data) {
  LOG4CXX_AUTO_TRACE(logger_);
  sync_primitives::AutoLock lock(launchers_lock_);
  DCHECK_OR_RETURN_VOID(!free_launchers_.empty())
  const AppLaunchers::iterator it = free_launchers_.begin();
  LauncherPtr app_launcher = *it;
  works_launchers_.push_back(app_launcher);
  free_launchers_.erase(it);
  app_launcher->PosponedLaunch(app_data);
}

struct AppLauncherFinder {
  AppLauncherFinder(const ApplicationDataPtr& app_data) : app_data_(app_data) {}
  bool operator()(const AppsLauncher::LauncherPtr& launcher) const {
    DCHECK_OR_RETURN(launcher->app_data_ && app_data_, false)
    return *launcher->app_data_ == *app_data_;
  }
  const ApplicationDataPtr& app_data_;
};

void AppsLauncher::StopLaunching(ApplicationDataPtr app_data) {
  sync_primitives::AutoLock lock(launchers_lock_);
  const AppLaunchers::iterator it = std::find_if(works_launchers_.begin(),
                                                 works_launchers_.end(),
                                                 AppLauncherFinder(app_data));
  if (it != works_launchers_.end()) {
    LauncherPtr launcher = *it;
    launcher->Clear();
    free_launchers_.push_back(launcher);
    works_launchers_.erase(it);
  } else {
    LOG4CXX_DEBUG(logger_,
                  "Unable to StopLaunching" << app_data->mobile_app_id_);
  }
}

void AppsLauncher::OnLaunched(ApplicationDataPtr app_data) {
  LOG4CXX_AUTO_TRACE(logger_);
  StopLaunching(app_data);
}

void AppsLauncher::OnRetryAttemptsExhausted(ApplicationDataPtr app_data) {
  LOG4CXX_AUTO_TRACE(logger_);
  StopLaunching(app_data);
}

AppsLauncher::Launcher::Launcher(
    AppsLauncher& parent,
    connection_handler::ConnectionHandler& connection_handler,
    const uint16_t app_launch_max_retry_attempt,
    const uint16_t app_launch_retry_wait_time)
    : retry_index_(0)
    , retry_timer_(
        "AppsLauncherTimer",
        new timer::TimerTaskImpl<Launcher>(this, &Launcher::LaunchNow))
    , app_launch_max_retry_attempt_(app_launch_max_retry_attempt)
    , app_launch_retry_wait_time_(app_launch_retry_wait_time)
    , connection_handler_(connection_handler)
    , parent_(parent) {}

void AppsLauncher::Launcher::PosponedLaunch(
    const app_launch::ApplicationDataPtr& app_data) {
  DCHECK(!app_data_);
  app_data_ = app_data;
  retry_index_ = 0;
  retry_timer_.Start(app_launch_retry_wait_time_, timer::kPeriodic);
  LOG4CXX_DEBUG(logger_,
                "Applicaiton " << app_data->mobile_app_id_ << " on device "
                               << app_data->device_mac_
                               << " will be launched in "
                               << app_launch_retry_wait_time_ << " ms");
}

void AppsLauncher::Launcher::Clear() {
  retry_timer_.Stop();
  app_data_.reset();
  retry_index_ = 0;
}

void AppsLauncher::Launcher::LaunchNow() {
  if (retry_index_++ < app_launch_max_retry_attempt_) {
    LOG4CXX_DEBUG(logger_,
                  "Run App " << app_data_->mobile_app_id_ << "with bundle "
                             << app_data_->bundle_id_ << " On Device "
                             << app_data_->device_mac_);

    connection_handler_.RunAppOnDevice(app_data_->device_mac_,
                                       app_data_->bundle_id_);
  } else {
    parent_.OnRetryAttemptsExhausted(app_data_);
  }
}

}  // namespace app_launch
<|endoftext|>


<commit_before>#include "buffer.h"
#include "../sockets/SocketW.h"
#include <iostream>

class user{
  public:
    user(SWBaseSocket * newConn);
    void disconnect(std::string reason);
    void Send(buffer ** ringbuf, int buffers);
    bool is_connected;
    SWUnixSocket * Conn;
    int MyBuffer;
    int MyBuffer_num;
    int MyBuffer_len;
    int MyNum;
    void * lastpointer;
    static int UserCount;
    static SWBaseSocket::SWBaseError err;
};//user

int user::UserCount = 0;
SWBaseSocket::SWBaseError user::err;

user::user(SWBaseSocket * newConn) {
  Conn = (SWUnixSocket*)newConn;
  is_connected = (Conn != 0);
  MyNum = UserCount++;
  std::cout << "User " << MyNum << " connected" << std::endl;
}

void user::disconnect(std::string reason) {
  if (Conn) {
    Conn->disconnect(&err);
    Conn = NULL;
    std::cout << "Disconnected user " << MyNum << ": " << reason << std::endl;
  }
  is_connected = false;
}

void user::Send(buffer ** ringbuf, int buffers){
  //not connected? cancel
  if (!is_connected){return;}
  //still waiting for next buffer? check it
  if (MyBuffer_num < 0){
    MyBuffer_num = ringbuf[MyBuffer]->number;
    //still waiting? don't crash - wait longer.
    if (MyBuffer_num < 0){
      return;
    }else{
      MyBuffer_len = ringbuf[MyBuffer]->FLV->len;
      lastpointer = ringbuf[MyBuffer]->FLV->data;
    }
  }
  if (lastpointer != ringbuf[MyBuffer]->FLV->data){
    disconnect("Buffer resize at wrong time... had to disconnect");
    return;
  }
  int ret = Conn->fsend(ringbuf[MyBuffer]->FLV->data, MyBuffer_len, &err);
  if ((err != SWBaseSocket::ok) && (err != SWBaseSocket::notReady)){
    disconnect("Socket error: " + err.get_error());
    return;
  }
  if (ret == MyBuffer_len){
    //completed a send - switch to next buffer
    if ((ringbuf[MyBuffer]->number != MyBuffer_num)){
      std::cout << "Warning: User " << MyNum << " was send corrupt video data and send to the next keyframe!" << std::endl;
      do{
        MyBuffer++;
        MyBuffer %= buffers;
      }while(!ringbuf[MyBuffer]->FLV->isKeyframe);
    }else{
      MyBuffer++;
      MyBuffer %= buffers;
    }
    MyBuffer_num = -1;
    lastpointer = 0;
  }
}
<commit_msg>Buffer crash probleem fixed<commit_after>#include "buffer.h"
#include "../sockets/SocketW.h"
#include <iostream>

class user{
  public:
    user(SWBaseSocket * newConn);
    void disconnect(std::string reason);
    void Send(buffer ** ringbuf, int buffers);
    bool is_connected;
    SWUnixSocket * Conn;
    int MyBuffer;
    int MyBuffer_num;
    int MyBuffer_len;
    int MyNum;
    void * lastpointer;
    static int UserCount;
    static SWBaseSocket::SWBaseError err;
};//user

int user::UserCount = 0;
SWBaseSocket::SWBaseError user::err;

user::user(SWBaseSocket * newConn) {
  Conn = (SWUnixSocket*)newConn;
  is_connected = (Conn != 0);
  MyNum = UserCount++;
  std::cout << "User " << MyNum << " connected" << std::endl;
}

void user::disconnect(std::string reason) {
  if (Conn) {
    Conn->disconnect(&err);
    Conn = NULL;
    std::cout << "Disconnected user " << MyNum << ": " << reason << std::endl;
  }
  is_connected = false;
}

void user::Send(buffer ** ringbuf, int buffers){
  //not connected? cancel
  if (!is_connected){return;}
  //still waiting for next buffer? check it
  if (MyBuffer_num < 0){
    MyBuffer_num = ringbuf[MyBuffer]->number;
    //still waiting? don't crash - wait longer.
    if (MyBuffer_num < 0){
      return;
    }else{
      MyBuffer_len = ringbuf[MyBuffer]->FLV->len;
      lastpointer = ringbuf[MyBuffer]->FLV->data;
    }
  }
  if (lastpointer != ringbuf[MyBuffer]->FLV->data){
    disconnect("Buffer resize at wrong time... had to disconnect");
    return;
  }
  int ret = Conn->fsend(ringbuf[MyBuffer]->FLV->data, MyBuffer_len, &err);
  if ((err != SWBaseSocket::ok) && (err != SWBaseSocket::notReady)){
    disconnect("Socket error: " + err.get_error());
    return;
  }
  if (ret == MyBuffer_len){
    //completed a send - switch to next buffer
    if ((ringbuf[MyBuffer]->number != MyBuffer_num)){
      std::cout << "Warning: User " << MyNum << " was send corrupt video data and send to the next keyframe!" << std::endl;
      int nocrashcount = 0;
      do{
        MyBuffer++;
        nocrashcount++;
        MyBuffer %= buffers;
      }while(!ringbuf[MyBuffer]->FLV->isKeyframe && (nocrashcount < buffers));
      if (nocrashcount >= buffers){
        std::cout << "Warning: No keyframe found in buffers! Skipping search for now..." << std::endl;
        return;
      }
    }else{
      MyBuffer++;
      MyBuffer %= buffers;
    }
    MyBuffer_num = -1;
    lastpointer = 0;
  }
}
<|endoftext|>