<commit_before>#include "3rd-party/catch.hpp"

#include <memory>

#include "cache.h"
#include "configcontainer.h"
#include "feedhandler.h"
#include "rss.h"
#include "test-helpers.h"

using namespace newsboat;

namespace {

std::vector<std::shared_ptr<rss_feed>> get_five_empty_feeds()
{
	std::vector<std::shared_ptr<rss_feed>> feeds;
	TestHelpers::TempFile dbfile;
	std::unique_ptr<configcontainer> cfg(new configcontainer());
	std::unique_ptr<cache> rsscache(new cache(dbfile.getPath(), cfg.get()));
	for (int i = 0; i < 5; ++i) {
		const auto feed = std::make_shared<rss_feed>(rsscache.get());
		feeds.push_back(feed);
	}
	return feeds;
}

} // anonymous namespace

TEST_CASE("get_feed() returns feed by its position number", "[feedhandler]")
{
	FeedHandler feedhandler;
	const auto feeds = get_five_empty_feeds();
	int i = 0;
	for (const auto& feed : feeds) {
		feed->set_title(std::to_string(i));
		feed->set_rssurl("url/" + std::to_string(i));
		i++;
	}
	feedhandler.set_feeds(feeds);

	auto feed = feedhandler.get_feed(0);
	REQUIRE(feed->title_raw() == "0");

	feed = feedhandler.get_feed(4);
	REQUIRE(feed->title_raw() == "4");
}

TEST_CASE("get_feed_by_url() returns feed by its URL", "[feedhandler]")
{
	FeedHandler feedhandler;
	const auto feeds = get_five_empty_feeds();
	int i = 0;
	for (const auto& feed : feeds) {
		feed->set_title(std::to_string(i));
		feed->set_rssurl("url/" + std::to_string(i));
		i++;
	}
	feedhandler.set_feeds(feeds);

	auto feed = feedhandler.get_feed_by_url("url/1");
	REQUIRE(feed->title_raw() == "1");

	feed = feedhandler.get_feed_by_url("url/4");
	REQUIRE(feed->title_raw() == "4");
}

TEST_CASE("Throws on get_feed() with pos out of range", "[feedhandler]")
{
	FeedHandler feedhandler;
	feedhandler.set_feeds(get_five_empty_feeds());

	REQUIRE_NOTHROW(feedhandler.get_feed(4));
	CHECK_THROWS_AS(feedhandler.get_feed(5), std::out_of_range);
	CHECK_THROWS_AS(feedhandler.get_feed(-1), std::out_of_range);
}

TEST_CASE("Returns correct number using get_feed_count_by_tag()", "[feedhandler]")
{
	FeedHandler feedhandler;
	feedhandler.set_feeds(get_five_empty_feeds());
	feedhandler.get_feed(0)->set_tags({"Chicken", "Horse"});
	feedhandler.get_feed(1)->set_tags({"Horse", "Duck"});
	feedhandler.get_feed(2)->set_tags({"Duck", "Frog"});
	feedhandler.get_feed(3)->set_tags({"Duck", "Hawk"});

	REQUIRE(feedhandler.get_feed_count_per_tag("Ice Cream") == 0);
	REQUIRE(feedhandler.get_feed_count_per_tag("Chicken") == 1);
	REQUIRE(feedhandler.get_feed_count_per_tag("Horse") == 2);
	REQUIRE(feedhandler.get_feed_count_per_tag("Duck") == 3);
}

TEST_CASE("Correctly returns pos of next unread item", "[feedhandler]")
{
	FeedHandler feedhandler;
	const auto feeds = get_five_empty_feeds();
	int i = 0;
	for (const auto& feed : feeds) {
		const auto item = std::make_shared<rss_item>(nullptr);
		if ((i % 2) == 0)
			item->set_unread_nowrite(true);
		else
			item->set_unread_nowrite(false);
		feed->add_item(item);
		i++;
	}
	feedhandler.set_feeds(feeds);

	REQUIRE(feedhandler.get_pos_of_next_unread(0) == 2);
	REQUIRE(feedhandler.get_pos_of_next_unread(2) == 4);
}

TEST_CASE("Correctly sorts feeds", "[feedhandler]")
{
	SECTION("by none asc")
	{
	}

	SECTION("by none desc")
	{
	}

	SECTION("by firsttag asc")
	{
	}

	SECTION("by firsttag desc")
	{
	}

	SECTION("by title asc")
	{
	}

	SECTION("by title desc")
	{
	}

	SECTION("by articlecount asc")
	{
	}

	SECTION("by articlecount desc")
	{
	}

	SECTION("by unreadarticlecount asc")
	{
	}

	SECTION("by unreadarticlecount desc")
	{
	}

	SECTION("by lastupdated asc")
	{
	}

	SECTION("by lastupdated desc")
	{
	}
}
<commit_msg>Use in-memory db in tests<commit_after>#include "3rd-party/catch.hpp"

#include <memory>

#include "cache.h"
#include "configcontainer.h"
#include "feedhandler.h"
#include "rss.h"
#include "test-helpers.h"

using namespace newsboat;

namespace {

std::vector<std::shared_ptr<rss_feed>> get_five_empty_feeds()
{
	std::vector<std::shared_ptr<rss_feed>> feeds;
	std::unique_ptr<configcontainer> cfg(new configcontainer());
	std::unique_ptr<cache> rsscache(new cache(":memory:", cfg.get()));
	for (int i = 0; i < 5; ++i) {
		const auto feed = std::make_shared<rss_feed>(rsscache.get());
		feeds.push_back(feed);
	}
	return feeds;
}

} // anonymous namespace

TEST_CASE("get_feed() returns feed by its position number", "[feedhandler]")
{
	FeedHandler feedhandler;
	const auto feeds = get_five_empty_feeds();
	int i = 0;
	for (const auto& feed : feeds) {
		feed->set_title(std::to_string(i));
		feed->set_rssurl("url/" + std::to_string(i));
		i++;
	}
	feedhandler.set_feeds(feeds);

	auto feed = feedhandler.get_feed(0);
	REQUIRE(feed->title_raw() == "0");

	feed = feedhandler.get_feed(4);
	REQUIRE(feed->title_raw() == "4");
}

TEST_CASE("get_feed_by_url() returns feed by its URL", "[feedhandler]")
{
	FeedHandler feedhandler;
	const auto feeds = get_five_empty_feeds();
	int i = 0;
	for (const auto& feed : feeds) {
		feed->set_title(std::to_string(i));
		feed->set_rssurl("url/" + std::to_string(i));
		i++;
	}
	feedhandler.set_feeds(feeds);

	auto feed = feedhandler.get_feed_by_url("url/1");
	REQUIRE(feed->title_raw() == "1");

	feed = feedhandler.get_feed_by_url("url/4");
	REQUIRE(feed->title_raw() == "4");
}

TEST_CASE("Throws on get_feed() with pos out of range", "[feedhandler]")
{
	FeedHandler feedhandler;
	feedhandler.set_feeds(get_five_empty_feeds());

	REQUIRE_NOTHROW(feedhandler.get_feed(4));
	CHECK_THROWS_AS(feedhandler.get_feed(5), std::out_of_range);
	CHECK_THROWS_AS(feedhandler.get_feed(-1), std::out_of_range);
}

TEST_CASE("Returns correct number using get_feed_count_by_tag()", "[feedhandler]")
{
	FeedHandler feedhandler;
	feedhandler.set_feeds(get_five_empty_feeds());
	feedhandler.get_feed(0)->set_tags({"Chicken", "Horse"});
	feedhandler.get_feed(1)->set_tags({"Horse", "Duck"});
	feedhandler.get_feed(2)->set_tags({"Duck", "Frog"});
	feedhandler.get_feed(3)->set_tags({"Duck", "Hawk"});

	REQUIRE(feedhandler.get_feed_count_per_tag("Ice Cream") == 0);
	REQUIRE(feedhandler.get_feed_count_per_tag("Chicken") == 1);
	REQUIRE(feedhandler.get_feed_count_per_tag("Horse") == 2);
	REQUIRE(feedhandler.get_feed_count_per_tag("Duck") == 3);
}

TEST_CASE("Correctly returns pos of next unread item", "[feedhandler]")
{
	FeedHandler feedhandler;
	const auto feeds = get_five_empty_feeds();
	int i = 0;
	for (const auto& feed : feeds) {
		const auto item = std::make_shared<rss_item>(nullptr);
		if ((i % 2) == 0)
			item->set_unread_nowrite(true);
		else
			item->set_unread_nowrite(false);
		feed->add_item(item);
		i++;
	}
	feedhandler.set_feeds(feeds);

	REQUIRE(feedhandler.get_pos_of_next_unread(0) == 2);
	REQUIRE(feedhandler.get_pos_of_next_unread(2) == 4);
}

TEST_CASE("Correctly sorts feeds", "[feedhandler]")
{
	SECTION("by none asc")
	{
	}

	SECTION("by none desc")
	{
	}

	SECTION("by firsttag asc")
	{
	}

	SECTION("by firsttag desc")
	{
	}

	SECTION("by title asc")
	{
	}

	SECTION("by title desc")
	{
	}

	SECTION("by articlecount asc")
	{
	}

	SECTION("by articlecount desc")
	{
	}

	SECTION("by unreadarticlecount asc")
	{
	}

	SECTION("by unreadarticlecount desc")
	{
	}

	SECTION("by lastupdated asc")
	{
	}

	SECTION("by lastupdated desc")
	{
	}
}
<|endoftext|>


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

#include "modules/canbus/vehicle/lincoln/protocol/wheelspeed_6a.h"

#include "glog/logging.h"

#include "modules/drivers/canbus/common/byte.h"

namespace apollo {
namespace canbus {
namespace lincoln {

using ::apollo::drivers::canbus::Byte;

const int32_t Wheelspeed6a::ID = 0x6A;

void Wheelspeed6a::Parse(const std::uint8_t *bytes, int32_t length,
                         ChassisDetail *chassis_detail) const {
  // how to set direction
  // what is "valid"
  // front left
  chassis_detail->mutable_vehicle_spd()->set_wheel_spd_fl(
      front_left_wheel_speed(bytes, length));
  chassis_detail->mutable_vehicle_spd()->set_is_wheel_spd_fl_valid(true);
  chassis_detail->mutable_vehicle_spd()->set_wheel_direction_fl(
      wheel_direction_convert(front_left_wheel_speed(bytes, length)));
  // front right
  chassis_detail->mutable_vehicle_spd()->set_wheel_spd_fr(
      front_right_wheel_speed(bytes, length));
  chassis_detail->mutable_vehicle_spd()->set_is_wheel_spd_fr_valid(true);
  chassis_detail->mutable_vehicle_spd()->set_wheel_direction_fr(
      wheel_direction_convert(front_right_wheel_speed(bytes, length)));
  // rear left
  chassis_detail->mutable_vehicle_spd()->set_wheel_spd_rl(
      rear_left_wheel_speed(bytes, length));
  chassis_detail->mutable_vehicle_spd()->set_is_wheel_spd_rl_valid(true);
  chassis_detail->mutable_vehicle_spd()->set_wheel_direction_rl(
      wheel_direction_convert(rear_left_wheel_speed(bytes, length)));
  // rear right
  chassis_detail->mutable_vehicle_spd()->set_wheel_spd_rr(
      rear_right_wheel_speed(bytes, length));
  chassis_detail->mutable_vehicle_spd()->set_is_wheel_spd_rr_valid(true);
  chassis_detail->mutable_vehicle_spd()->set_wheel_direction_rr(
      wheel_direction_convert(rear_right_wheel_speed(bytes, length)));
  /*
  -?(rr(bytes, length));
  -?(rl(bytes, length));
  -?(fr(bytes, length));
  -?(fl(bytes, length));*/
}

void Wheelspeed6a::Parse(const std::uint8_t *bytes, int32_t length,
                         const struct timeval &timestamp,
                         ChassisDetail *chassis_detail) const {
  chassis_detail->mutable_vehicle_spd()->set_timestamp_sec(
      static_cast<double>(timestamp.tv_sec) +
      static_cast<double>(timestamp.tv_usec) / 1000000.0);
  Parse(bytes, length, chassis_detail);
}

double Wheelspeed6a::front_left_wheel_speed(const std::uint8_t *bytes,
                                            int32_t length) const {
  DCHECK_GE(length, 2);
  return parse_two_frames(bytes[0], bytes[1]);
}

double Wheelspeed6a::front_right_wheel_speed(const std::uint8_t *bytes,
                                             int32_t length) const {
  DCHECK_GE(length, 4);
  return parse_two_frames(bytes[2], bytes[3]);
}

double Wheelspeed6a::rear_left_wheel_speed(const std::uint8_t *bytes,
                                           int32_t length) const {
  DCHECK_GE(length, 6);
  return parse_two_frames(bytes[4], bytes[5]);
}

double Wheelspeed6a::rear_right_wheel_speed(const std::uint8_t *bytes,
                                            int32_t length) const {
  DCHECK_GE(length, 8);
  return parse_two_frames(bytes[6], bytes[7]);
}

double Wheelspeed6a::parse_two_frames(const std::uint8_t low_byte,
                                      const std::uint8_t high_byte) const {
  Byte high_frame(&high_byte);
  int32_t high = high_frame.get_byte(0, 8);
  Byte low_frame(&low_byte);
  int32_t low = low_frame.get_byte(0, 8);
  int32_t value = (high << 8) | low;
  if (value > 0x7FFF) {
    value -= 0x10000;
  }
  return value * 0.010000;
}

WheelSpeed::WheelSpeedType Wheelspeed6a::wheel_direction_convert(
    double wheel_speed) const {
  int8_t wheel_direction = 0;
  if (wheel_speed > 0) {
    wheel_direction = 0;
  } else if ((wheel_speed > -0.01) && (wheel_speed < 0.01)) {
    wheel_direction = 2;
  } else if (wheel_speed < 0) {
    wheel_direction = 1;
  } else {
    wheel_direction = 3;
  }
  WheelSpeed::WheelSpeedType ret =
      static_cast<WheelSpeed::WheelSpeedType>(wheel_direction);
  return ret;
}

}  // namespace lincoln
}  // namespace canbus
}  // namespace apollo
<commit_msg>Canbus: fix the suggestion<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/canbus/vehicle/lincoln/protocol/wheelspeed_6a.h"

#include "glog/logging.h"

#include "modules/drivers/canbus/common/byte.h"

namespace apollo {
namespace canbus {
namespace lincoln {

using ::apollo::drivers::canbus::Byte;

const int32_t Wheelspeed6a::ID = 0x6A;

void Wheelspeed6a::Parse(const std::uint8_t *bytes, int32_t length,
                         ChassisDetail *chassis_detail) const {
  // how to set direction
  // what is "valid"
  // front left
  chassis_detail->mutable_vehicle_spd()->set_wheel_spd_fl(
      front_left_wheel_speed(bytes, length));
  chassis_detail->mutable_vehicle_spd()->set_is_wheel_spd_fl_valid(true);
  chassis_detail->mutable_vehicle_spd()->set_wheel_direction_fl(
      wheel_direction_convert(front_left_wheel_speed(bytes, length)));
  // front right
  chassis_detail->mutable_vehicle_spd()->set_wheel_spd_fr(
      front_right_wheel_speed(bytes, length));
  chassis_detail->mutable_vehicle_spd()->set_is_wheel_spd_fr_valid(true);
  chassis_detail->mutable_vehicle_spd()->set_wheel_direction_fr(
      wheel_direction_convert(front_right_wheel_speed(bytes, length)));
  // rear left
  chassis_detail->mutable_vehicle_spd()->set_wheel_spd_rl(
      rear_left_wheel_speed(bytes, length));
  chassis_detail->mutable_vehicle_spd()->set_is_wheel_spd_rl_valid(true);
  chassis_detail->mutable_vehicle_spd()->set_wheel_direction_rl(
      wheel_direction_convert(rear_left_wheel_speed(bytes, length)));
  // rear right
  chassis_detail->mutable_vehicle_spd()->set_wheel_spd_rr(
      rear_right_wheel_speed(bytes, length));
  chassis_detail->mutable_vehicle_spd()->set_is_wheel_spd_rr_valid(true);
  chassis_detail->mutable_vehicle_spd()->set_wheel_direction_rr(
      wheel_direction_convert(rear_right_wheel_speed(bytes, length)));
  /*
  -?(rr(bytes, length));
  -?(rl(bytes, length));
  -?(fr(bytes, length));
  -?(fl(bytes, length));*/
}

void Wheelspeed6a::Parse(const std::uint8_t *bytes, int32_t length,
                         const struct timeval &timestamp,
                         ChassisDetail *chassis_detail) const {
  chassis_detail->mutable_vehicle_spd()->set_timestamp_sec(
      static_cast<double>(timestamp.tv_sec) +
      static_cast<double>(timestamp.tv_usec) / 1000000.0);
  Parse(bytes, length, chassis_detail);
}

double Wheelspeed6a::front_left_wheel_speed(const std::uint8_t *bytes,
                                            int32_t length) const {
  DCHECK_GE(length, 2);
  return parse_two_frames(bytes[0], bytes[1]);
}

double Wheelspeed6a::front_right_wheel_speed(const std::uint8_t *bytes,
                                             int32_t length) const {
  DCHECK_GE(length, 4);
  return parse_two_frames(bytes[2], bytes[3]);
}

double Wheelspeed6a::rear_left_wheel_speed(const std::uint8_t *bytes,
                                           int32_t length) const {
  DCHECK_GE(length, 6);
  return parse_two_frames(bytes[4], bytes[5]);
}

double Wheelspeed6a::rear_right_wheel_speed(const std::uint8_t *bytes,
                                            int32_t length) const {
  DCHECK_GE(length, 8);
  return parse_two_frames(bytes[6], bytes[7]);
}

double Wheelspeed6a::parse_two_frames(const std::uint8_t low_byte,
                                      const std::uint8_t high_byte) const {
  Byte high_frame(&high_byte);
  int32_t high = high_frame.get_byte(0, 8);
  Byte low_frame(&low_byte);
  int32_t low = low_frame.get_byte(0, 8);
  int32_t value = (high << 8) | low;
  if (value > 0x7FFF) {
    value -= 0x10000;
  }
  return value * 0.010000;
}

WheelSpeed::WheelSpeedType Wheelspeed6a::wheel_direction_convert(
    double wheel_speed) const {
  WheelSpeed::WheelSpeedType wheel_direction = WheelSpeed::INVALID;
  if (wheel_speed > 0) {
    wheel_direction = WheelSpeed::FORWARD;
  } else if ((wheel_speed > -0.01) && (wheel_speed < 0.01)) {
    wheel_direction = WheelSpeed::STANDSTILL;
  } else if (wheel_speed < 0) {
    wheel_direction = WheelSpeed::BACKWARD;
  } else {
    wheel_direction = WheelSpeed::INVALID;
  }
  return wheel_direction;
}

}  // namespace lincoln
}  // namespace canbus
}  // namespace apollo
<|endoftext|>


<commit_before><commit_msg>Create KCswerve310.cpp<commit_after><|endoftext|>


<commit_before>
#include "glbinding.h"

#include <iostream>
#include <sstream>

#include <glbinding/gl/gl.h>

#include <glbinding/AbstractFunction.h>
#include <glbinding/callbacks.h>

using namespace gl;

namespace
{
    #include "gltest_data.inl"
}

void glbinding_init()
{
    glbinding::Binding::initialize(false);
}

void glbinding_test()
{
    #include "gltest.inl"
}

void glbinding_error(bool enable)
{
    if (enable)
    {
        glbinding::setCallbackMaskExcept(glbinding::CallbackMask::After, { "glGetError" });

        glbinding::setAfterCallback([](const glbinding::FunctionCall &)
        {
            gl::GLenum error = gl::glGetError();
            if (error != gl::GL_NO_ERROR)
                std::cout << "Error: " << error << std::endl;
        });
    }
    else
        glbinding::setCallbackMask(glbinding::CallbackMask::None);
}
<commit_msg>Remove sstream include<commit_after>
#include "glbinding.h"

#include <iostream>

#include <glbinding/gl/gl.h>

#include <glbinding/AbstractFunction.h>
#include <glbinding/callbacks.h>

using namespace gl;

namespace
{
    #include "gltest_data.inl"
}

void glbinding_init()
{
    glbinding::Binding::initialize(false);
}

void glbinding_test()
{
    #include "gltest.inl"
}

void glbinding_error(bool enable)
{
    if (enable)
    {
        glbinding::setCallbackMaskExcept(glbinding::CallbackMask::After, { "glGetError" });

        glbinding::setAfterCallback([](const glbinding::FunctionCall &)
        {
            gl::GLenum error = gl::glGetError();
            if (error != gl::GL_NO_ERROR)
                std::cout << "Error: " << error << std::endl;
        });
    }
    else
        glbinding::setCallbackMask(glbinding::CallbackMask::None);
}
<|endoftext|>


<commit_before>// main.cpp : Defines the entry point for the console application.
#include "monik/third_party/cmdLine/cmdLine.h"
#include "monik/log/logger_config.h"
#include "monik/log/logger.h"
#include "monik/log/log_define.h"
#include "monik/common/locale.h"
#include <fstream>
#include <thread>

namespace {

using namespace monik;

struct cmd_option : noncopyable {
    struct {
        std::string config;
        std::string message;
        std::string severity;
        std::string source;
    } log;
};

void trace_log(cmd_option const & opt)
{
    if (!opt.log.config.empty()) {
        std::cout
            << "\nlog_config = " << opt.log.config
            << "\nlog_message = " << opt.log.message
            << "\nlog_severity = " << opt.log.severity
            << "\nlog_source = " << opt.log.source
            << std::endl;
        using T = log::logger::ST;
        if (log::logger_config::setup_logs_file(T::instance(), opt.log.config.c_str())) {
            if (!opt.log.message.empty()) {
                log::severity t = log::severity::trace;
                if (!opt.log.severity.empty()) {
                    t = log::logger::from_string(opt.log.severity.c_str());
                    MONIK_ASSERT(log::logger::to_string(t) == opt.log.severity);
                }
                T::cinstance().log(t, opt.log.message, opt.log.source.c_str());
            }
            if (0) { // test api
                MONIK_LOG_TRACE(__FUNCTION__, " at line ", __LINE__);
                MONIK_LOG_TRACE_SOURCE(__FILE__);
            }
        }
        else {
            MONIK_ASSERT(0);
        }
    }
    if (0) {
        for (size_t i = 0; i < 30; ++i) {
            std::cout << ".";
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    }
}

void print_version()
{
#if defined(NDEBUG)
    std::cout << "\nNDEBUG version";
#else
    std::cout << "\nDEBUG version";
#endif
#if MONIK_DEBUG
    std::cout << "\nMONIK_DEBUG=1";
#else
    std::cout << "\nMONIK_DEBUG=0";
#endif
    std::cout
        << "\nBuild date: " << __DATE__
        << "\nBuild time: " << __TIME__
        << std::endl;
}

void print_help(int argc, char* argv[])
{
    (void)argc;
    print_version();
    std::cout
        << "\nUsage: " << argv[0]
        << "\n[--log_config] json config file"
        << "\n[--log_message] test message"
        << "\n[--log_severity] trace|debug|info|warning|error|fatal"
        << "\n[--log_source] system|application|logic|security"
        << std::endl;
}

// C++ option parser library, supporting the standard GNU style syntax for options.
//FIXME: https://github.com/jarro2783/cxxopts

int run_main(int argc, char* argv[])
{
    setlocale_t::set("Russian");
    cmd_option opt{};
    CmdLine cmd;
#if MONIK_DEBUG
    cmd.add(make_option(0, debug::warning_level(), "warning"));
#endif
    cmd.add(make_option(0, opt.log.config, "log_config"));
    cmd.add(make_option(0, opt.log.message, "log_message"));
    cmd.add(make_option(0, opt.log.severity, "log_severity"));
    cmd.add(make_option(0, opt.log.source, "log_source"));
    try {
        if (argc == 1) {
            print_help(argc, argv);
            std::cout << "\nMissing parameters" << std::endl;
            return EXIT_SUCCESS;
        }
        cmd.process(argc, argv);
        if (!opt.log.config.empty()) {
            trace_log(opt);
        }
        else {
            throw std::string("Missing parameters");
        }
    }
    catch (const std::string& s) {
        print_help(argc, argv);
        std::cerr << "\n" << s << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

} // namespace

int main(int argc, char* argv[])
{
    try {
        const int ret = run_main(argc, argv);
        return ret;
    }
    catch (sdl_exception & e) {
        (void)e;
        std::cout << "\ncatch exception [" << typeid(e).name() << "] = " << e.what();
        MONIK_ASSERT(0);
    }
    catch (std::exception & e) {
        (void)e;
        std::cout << "\ncatch std::exception = " << e.what();
        MONIK_ASSERT(0);
    }
}

<commit_msg>test monik<commit_after>// main.cpp : Defines the entry point for the console application.
#include "monik/third_party/cmdLine/cmdLine.h"
#include "monik/log/logger_config.h"
#include "monik/log/logger.h"
#include "monik/log/log_define.h"
#include "monik/common/locale.h"
#include <fstream>
#include <thread>

namespace {

using namespace monik;

struct cmd_option final : noncopyable {
    struct {
        std::string config;
        std::string message;
        std::string severity;
        std::string source;
    } log;
};

void trace_log(cmd_option const & opt)
{
    if (!opt.log.config.empty()) {
        std::cout
            << "\nconfig = " << opt.log.config
            << "\nmessage = " << opt.log.message
            << "\nseverity = " << opt.log.severity
            << "\nsource = " << opt.log.source
            << std::endl;
        using T = log::logger::ST;
        if (log::logger_config::setup_logs_file(T::instance(), opt.log.config.c_str())) {
            if (!opt.log.message.empty()) {
                log::severity t = log::severity::trace;
                if (!opt.log.severity.empty()) {
                    t = log::logger::from_string(opt.log.severity.c_str());
                    MONIK_ASSERT(log::logger::to_string(t) == opt.log.severity);
                }
                T::cinstance().log(t, opt.log.message, opt.log.source.c_str());
            }
            if (0) { // test api
                MONIK_LOG_TRACE(__FUNCTION__, " at line ", __LINE__);
                MONIK_LOG_TRACE_SOURCE(__FILE__);
            }
        }
        else {
            MONIK_ASSERT(0);
        }
    }
    if (0) {
        for (size_t i = 0; i < 30; ++i) {
            std::cout << ".";
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    }
}

void print_version()
{
#if defined(NDEBUG)
    std::cout << "\nNDEBUG version";
#else
    std::cout << "\nDEBUG version";
#endif
#if MONIK_DEBUG
    std::cout << "\nMONIK_DEBUG=1";
#else
    std::cout << "\nMONIK_DEBUG=0";
#endif
    std::cout
        << "\nBuild date: " << __DATE__
        << "\nBuild time: " << __TIME__
        << std::endl;
}

void print_help(int argc, char* argv[])
{
    (void)argc;
    print_version();
    std::cout
        << "\nUsage: " << argv[0]
        << "\n[-i|--config] json config file"
        << "\n[-m|--message] test message"
        << "\n[-s|--severity] trace|debug|info|warning|error|fatal"
        << "\n[-u|--source] system|application|logic|security"
        << std::endl;
}

// C++ option parser library, supporting the standard GNU style syntax for options.
//FIXME: https://github.com/jarro2783/cxxopts

int run_main(int argc, char* argv[])
{
    setlocale_t::set("Russian");
    cmd_option opt{};
    CmdLine cmd;
#if MONIK_DEBUG
    cmd.add(make_option(0, debug::warning_level(), "warning"));
#endif
    cmd.add(make_option('i', opt.log.config, "config"));
    cmd.add(make_option('m', opt.log.message, "message"));
    cmd.add(make_option('s', opt.log.severity, "severity"));
    cmd.add(make_option('u', opt.log.source, "source"));
    try {
        if (argc == 1) {
            print_help(argc, argv);
            std::cout << "\nMissing parameters" << std::endl;
            return EXIT_SUCCESS;
        }
        cmd.process(argc, argv);
        if (!opt.log.config.empty()) {
            trace_log(opt);
        }
        else {
            throw std::string("Missing parameters");
        }
    }
    catch (const std::string& s) {
        print_help(argc, argv);
        std::cerr << "\n" << s << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

} // namespace

int main(int argc, char* argv[])
{
    try {
        const int ret = run_main(argc, argv);
        return ret;
    }
    catch (sdl_exception & e) {
        (void)e;
        std::cout << "\ncatch exception [" << typeid(e).name() << "] = " << e.what();
        MONIK_ASSERT(0);
    }
    catch (std::exception & e) {
        (void)e;
        std::cout << "\ncatch std::exception = " << e.what();
        MONIK_ASSERT(0);
    }
}

<|endoftext|>


<commit_before>// Copyright (C) 2018 Elviss Strazdins
// This file is part of the Ouzel engine.

#pragma once

#include <functional>
#include <memory>
#include <string>
#if defined(_MSC_VER)
#include <Windows.h>
#else
#include <pthread.h>
#endif

namespace ouzel
{
    class Thread final
    {
    public:
        class ID
        {
            friend Thread;
        public:
            bool operator==(const ID& other)
            {
#if defined(_MSC_VER)
                return threadId == other.threadId;
#else
                return pthread_equal(thread, other.thread) != 0;
#endif
            }

            bool operator!=(const ID& other)
            {
#if defined(_MSC_VER)
                return threadId != other.threadId;
#else
                return pthread_equal(thread, other.thread) == 0;
#endif
            }

        protected:
#if defined(_MSC_VER)
            ID(DWORD id):
                threadId(id)
#else
            ID(pthread_t t):
                thread(t)
#endif
            {
            }
        private:
#if defined(_MSC_VER)
            DWORD threadId = 0;
#else
            pthread_t thread = 0;
#endif
        };

        Thread() {}
        explicit Thread(const std::function<void()>& function, const std::string& name = "");

        ~Thread();

        Thread(const Thread&) = delete;
        Thread& operator=(const Thread&) = delete;

        Thread(Thread&& other);
        Thread& operator=(Thread&& other);

        bool run();
        bool join();

        inline bool isJoinable() const
        {
#if defined(_MSC_VER)
            return handle != nullptr;
#else
            return thread != 0;
#endif
        }

        ID getId() const
        {
#if defined(_MSC_VER)
            return threadId;
#else
            return thread;
#endif
        }

        static ID getCurrentThreadId()
        {
#if defined(_MSC_VER)
            return GetCurrentThreadId();
#else
            return pthread_self();
#endif
        }

        static bool setCurrentThreadName(const std::string& name);

        struct State
        {
            std::function<void()> function;
            std::string name;
        };

    protected:
        std::unique_ptr<State> state;

#if defined(_MSC_VER)
        HANDLE handle = nullptr;
        DWORD threadId = 0;
#else
        pthread_t thread = 0;
#endif
    };
}
<commit_msg>Add define for ThreadLocal<commit_after>// Copyright (C) 2018 Elviss Strazdins
// This file is part of the Ouzel engine.

#pragma once

#include <functional>
#include <memory>
#include <string>
#if defined(_MSC_VER)
#include <Windows.h>
#define ThreadLocal __declspec(thread)
#else
#include <pthread.h>
#define ThreadLocal __thread
#endif

namespace ouzel
{
    class Thread final
    {
    public:
        class ID
        {
            friend Thread;
        public:
            bool operator==(const ID& other)
            {
#if defined(_MSC_VER)
                return threadId == other.threadId;
#else
                return pthread_equal(thread, other.thread) != 0;
#endif
            }

            bool operator!=(const ID& other)
            {
#if defined(_MSC_VER)
                return threadId != other.threadId;
#else
                return pthread_equal(thread, other.thread) == 0;
#endif
            }

        protected:
#if defined(_MSC_VER)
            ID(DWORD id):
                threadId(id)
#else
            ID(pthread_t t):
                thread(t)
#endif
            {
            }
        private:
#if defined(_MSC_VER)
            DWORD threadId = 0;
#else
            pthread_t thread = 0;
#endif
        };

        Thread() {}
        explicit Thread(const std::function<void()>& function, const std::string& name = "");

        ~Thread();

        Thread(const Thread&) = delete;
        Thread& operator=(const Thread&) = delete;

        Thread(Thread&& other);
        Thread& operator=(Thread&& other);

        bool run();
        bool join();

        inline bool isJoinable() const
        {
#if defined(_MSC_VER)
            return handle != nullptr;
#else
            return thread != 0;
#endif
        }

        ID getId() const
        {
#if defined(_MSC_VER)
            return threadId;
#else
            return thread;
#endif
        }

        static ID getCurrentThreadId()
        {
#if defined(_MSC_VER)
            return GetCurrentThreadId();
#else
            return pthread_self();
#endif
        }

        static bool setCurrentThreadName(const std::string& name);

        struct State
        {
            std::function<void()> function;
            std::string name;
        };

    protected:
        std::unique_ptr<State> state;

#if defined(_MSC_VER)
        HANDLE handle = nullptr;
        DWORD threadId = 0;
#else
        pthread_t thread = 0;
#endif
    };
}
<|endoftext|>


<commit_before>#include <QtCore>
#include <QtGui>
#include <QtQuick>

class FpsDecider : public QWindow
{
public:
    FpsDecider()
        : gl(0)
        , frameCount(0)
    {
        setSurfaceType(OpenGLSurface);
        QSurfaceFormat format;
#if QT_VERSION >= 0x050300
        format.setSwapInterval(1);
#endif
        setFormat(format);
    }

    void exposeEvent(QExposeEvent *) {
        if (isExposed())
            render();
    }

    bool event(QEvent *e)
    {
        if (e->type() == QEvent::UpdateRequest) {
            render();
            return true;
        }
        return QWindow::event(e);
    }

    void render()
    {
        if (!gl) {
            gl = new QOpenGLContext();
            gl->setFormat(format());
            gl->create();
            timer.start();
        }

        gl->makeCurrent(this);
        QOpenGLFunctions *func = gl->functions();

        if (frameCount == 0) {
#if QT_VERSION >= 0x050300
            qDebug() << "GL_VENDOR:  " << (const char *) func->glGetString(GL_VENDOR);
            qDebug() << "GL_RENDERER:" << (const char *) func->glGetString(GL_RENDERER);
            qDebug() << "GL_VERSION: " << (const char *) func->glGetString(GL_VERSION);
#else
            Q_UNUSED(func);
            qDebug() << "GL_VENDOR:  " << (const char *) glGetString(GL_VENDOR);
            qDebug() << "GL_RENDERER:" << (const char *) glGetString(GL_RENDERER);
            qDebug() << "GL_VERSION: " << (const char *) glGetString(GL_VERSION);
#endif
        }

        ++frameCount;
        int c = frameCount % 2;

#if QT_VERSION >= 0x050300
        func->glClearColor(c, 0, 1 - c, 1);
        func->glClear(GL_COLOR_BUFFER_BIT);
#else
        glClearColor(c, 0, 1 - c, 1);
        glClear(GL_COLOR_BUFFER_BIT);
#endif

        gl->swapBuffers(this);

        int time = timer.elapsed();
        if (time > 5000) {
            qDebug() << endl
                     << "FPS:" << frameCount * 1000 / float(time)
                     << " -- " << frameCount << "frames in" << time << "ms;"
                     << time / float(frameCount) << "ms/frame" << endl;
            exit(0);

        } else {
            QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
        }
    }

private:
    QOpenGLContext *gl;
    QElapsedTimer timer;
    int frameCount;
};

struct Options
{
    Options()
        : fullscreen(false)
        , verbose(false)
        , repeat(1)
        , fpsTolerance(0.05)
        , fpsInterval(1000)
        , fpsOverride(0)
    {
    }

    QString bmTemplate;
    bool fullscreen;
    bool verbose;
    int repeat;
    qreal fpsTolerance;
    qreal fpsInterval;
    qreal fpsOverride;
    qreal targetFps;
};

struct Benchmark
{
    Benchmark(const QString &file)
        : fileName(file)
        , completed(false)
    {
    }

    QString fileName;
    QSize windowSize;

    bool completed;
    QList<qreal> operationsPerFrame;
};

class BenchmarkRunner : public QObject
{
    Q_OBJECT

    // None of these are strictly constant, but for the sake of one QML run, they are
    // so flag it for simplicity
    Q_PROPERTY(QQuickView *view READ view CONSTANT)
    Q_PROPERTY(QQmlComponent *component READ component CONSTANT)
    Q_PROPERTY(qreal screeRefreshRate READ screenRefreshRate CONSTANT)
    Q_PROPERTY(QString input READ input CONSTANT)
    Q_PROPERTY(qreal fpsTolerance READ fpsTolerance CONSTANT)
    Q_PROPERTY(qreal fpsInterval READ fpsInterval CONSTANT)
    Q_PROPERTY(bool verbose READ verbose CONSTANT)

public:
    BenchmarkRunner();
    ~BenchmarkRunner();

    bool execute();

    QList<Benchmark> benchmarks;
    Options options;

    QQuickView *view() const { return m_view; }
    QQmlComponent *component() const { return m_component; }
    qreal screenRefreshRate() const { return options.fpsOverride > 0 ? options.fpsOverride : m_view->screen()->refreshRate(); }
    QString input() const { return benchmarks[m_currentBenchmark].fileName; }

    qreal fpsTolerance() const { return options.fpsTolerance / 100.0; }
    qreal fpsInterval() const { return options.fpsInterval; }

    bool verbose() const { return options.verbose; }

public slots:
    void recordOperationsPerFrame(qreal count);
    void complete();
    void abort();

private slots:
    void start();
    void maybeStartNext();

private:
    void abortAll();

    int m_currentBenchmark;

    QQuickView *m_view;
    QQmlComponent *m_component;
};

int main(int argc, char **argv)
{
    qmlRegisterType<QQuickView>();

	QGuiApplication app(argc, argv);

	QCommandLineParser parser;

    QCommandLineOption decideFpsOption(QStringLiteral("decide-fps"), QStringLiteral("Run a simple test to decide the frame rate of the primary screen"));
    parser.addOption(decideFpsOption);

    QCommandLineOption verboseOption(QStringList() << QStringLiteral("v") << QStringLiteral("verbose"),
                                     QStringLiteral("Verbose mode"));
    parser.addOption(verboseOption);

    QCommandLineOption repeatOption(QStringLiteral("repeat"),
                                         QStringLiteral("Sets the number of times to repeat the benchmark, to get more stable results"),
                                         QStringLiteral("iterations"),
                                         QStringLiteral("1"));
    parser.addOption(repeatOption);

    QCommandLineOption fpsIntervalOption(QStringLiteral("fps-interval"),
                                         QStringLiteral("Set the interval used to measure framerate in ms. Higher values lead to more stable test results"),
                                         QStringLiteral("interval"),
                                         QStringLiteral("1000"));
    parser.addOption(fpsIntervalOption);

    QCommandLineOption fpsToleranceOption(QStringLiteral("fps-tolerance"),
                                          QStringLiteral("The amount of deviance tolerated from the target frame rate in %. Lower value leads to more accurate results"),
                                          QStringLiteral("tolerance"),
                                          QStringLiteral("5"));
    parser.addOption(fpsToleranceOption);

    QCommandLineOption fpsOverrideOption(QStringLiteral("fps-override"),
                                         QStringLiteral("Override QScreen::refreshRate() with a custom refreshrate"),
                                         QStringLiteral("framerate"));
    parser.addOption(fpsOverrideOption);

    QCommandLineOption fullscreenOption(QStringLiteral("fullscreen"), QStringLiteral("Run graphics in fullscreen mode"));
    parser.addOption(fullscreenOption);

    QCommandLineOption templateOption(QStringList() << QStringLiteral("s") << QStringLiteral("shell"),
                                      QStringLiteral("What kind of benchmark shell to run. Available options are: 'sustained-fps'"),
                                      QStringLiteral("template"));
    parser.addOption(templateOption);

    parser.addPositionalArgument(QStringLiteral("input"),
                                 QStringLiteral("One or more QML files or a directory of QML files to benchmark"));
    const QCommandLineOption &helpOption = parser.addHelpOption();

    parser.process(app);

    if (parser.isSet(decideFpsOption)) {
        FpsDecider fpsDecider;
        if (parser.isSet(fullscreenOption))
            fpsDecider.showFullScreen();
        else
            fpsDecider.show();
        fpsDecider.raise();
        return app.exec();
    }

    if (parser.isSet(helpOption) || parser.positionalArguments().size() == 0) {
        parser.showHelp(0);
    }

    BenchmarkRunner runner;
    runner.options.verbose = parser.isSet(verboseOption);
    runner.options.fullscreen = parser.isSet(fullscreenOption);
    runner.options.repeat = qMax<int>(1, parser.value(repeatOption).toInt());
    runner.options.fpsInterval = qMax<qreal>(500, parser.value(fpsIntervalOption).toFloat());
    runner.options.fpsTolerance = qMax<qreal>(1, parser.value(fpsToleranceOption).toFloat());
    runner.options.bmTemplate = parser.value(templateOption);
    if (parser.isSet(fpsOverrideOption))
        runner.options.fpsOverride = parser.value(fpsOverrideOption).toFloat();

    if (runner.options.bmTemplate == QStringLiteral("sustained-fps"))
        runner.options.bmTemplate = QStringLiteral("qrc:/Shell_SustainedFpsWithCount.qml");
    else
        runner.options.bmTemplate = QStringLiteral("qrc:/Shell_SustainedFpsWithCount.qml");

    foreach (QString input, parser.positionalArguments()) {
        QFileInfo info(input);
        if (!info.exists()) {
            qDebug() << "input doesn't exist:" << input;
        } else if (info.suffix() == QStringLiteral("qml")) {
            runner.benchmarks << Benchmark(info.absoluteFilePath());
        } else if (info.isDir()) {
            QDirIterator iterator(input, QStringList() << QStringLiteral("*.qml"));
            while (iterator.hasNext()) {
                runner.benchmarks << Benchmark(iterator.next());
            }
        }
    }

    if (runner.options.verbose) {
        qDebug() << "Frame Rate .........:" << (runner.options.fpsOverride > 0 ? runner.options.fpsOverride : QGuiApplication::primaryScreen()->refreshRate());
        qDebug() << "Fullscreen .........:" << (runner.options.fullscreen ? "yes" : "no");
        qDebug() << "Fullscreen .........:" << (runner.options.fullscreen ? "yes" : "no");
        qDebug() << "Fps Interval .......:" << runner.options.fpsInterval;
        qDebug() << "Fps Tolerance ......:" << runner.options.fpsTolerance;
        qDebug() << "Template ...........:" << runner.options.bmTemplate;
        qDebug() << "Benchmarks:";
        foreach (const Benchmark &b, runner.benchmarks) {
            qDebug() << " -" << b.fileName;
        }
    }

    if (!runner.execute())
        return 0;

    return app.exec();
}

BenchmarkRunner::BenchmarkRunner()
    : m_currentBenchmark(0)
    , m_view(0)
{
}

BenchmarkRunner::~BenchmarkRunner()
{
    delete m_view;
}

bool BenchmarkRunner::execute()
{
    m_currentBenchmark = 0;
    if (benchmarks.size() == 0)
        return false;
    QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
    return true;
}

void BenchmarkRunner::start()
{
    Benchmark &bm = benchmarks[m_currentBenchmark];

    if (bm.operationsPerFrame.size() == 0)
        qDebug() << "running:" << bm.fileName;

    bool viewWasJustAdded = false;
    if (!m_view) {
        viewWasJustAdded = true;
        m_view = new QQuickView();
        // Make sure proper fullscreen is possible on OSX
        m_view->setFlags(Qt::Window
                         | Qt::WindowSystemMenuHint
                         | Qt::WindowTitleHint
                         | Qt::WindowMinMaxButtonsHint
                         | Qt::WindowCloseButtonHint
                         | Qt::WindowFullscreenButtonHint);
        m_view->setResizeMode(QQuickView::SizeRootObjectToView);
        m_view->rootContext()->setContextProperty("benchmark", this);
    }

    m_component = new QQmlComponent(m_view->engine(), bm.fileName);
    if (m_component->status() != QQmlComponent::Ready) {
        qDebug() << "component is not ready" << bm.fileName;
        abort();
        return;
    }

    m_view->setSource(QUrl(options.bmTemplate));
    if (!m_view->rootObject()) {
        qDebug() << "no root object..";
        abortAll();
        return;
    }

    if (viewWasJustAdded) {
        if (options.fullscreen)
            m_view->showFullScreen();
        else
            m_view->show();
        m_view->raise();
    }

    bm.windowSize = m_view->size();
}

void BenchmarkRunner::maybeStartNext()
{

    ++m_currentBenchmark;
    if (m_currentBenchmark < benchmarks.size()) {
        QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
    } else {
        qDebug() << "All done...";
        qApp->quit();
    }
}

void BenchmarkRunner::abort()
{
    maybeStartNext();
}

void BenchmarkRunner::abortAll()
{
    qDebug() << "Aborting all benchmarks...";
    qApp->quit();
}

void BenchmarkRunner::recordOperationsPerFrame(qreal ops)
{
    Benchmark &bm = benchmarks[m_currentBenchmark];
    bm.completed = true;
    bm.operationsPerFrame << ops;
    qDebug() << "    " << ops << "ops/frame";
    if (bm.operationsPerFrame.size() == options.repeat && options.repeat > 1) {
        qreal avg = 0;
        foreach (qreal r, bm.operationsPerFrame) avg += r;
        qDebug() << "    " << (avg / options.repeat) << "ops/frame average";
    }
    complete();
}

void BenchmarkRunner::complete()
{
    m_component->deleteLater();
    m_component = 0;
    if (benchmarks[m_currentBenchmark].operationsPerFrame.size() < options.repeat)
        QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
    else
        QMetaObject::invokeMethod(this, "maybeStartNext", Qt::QueuedConnection);
}

#include "main.moc"
<commit_msg>add --width, --height --delay options<commit_after>#include <QtCore>
#include <QtGui>
#include <QtQuick>

class FpsDecider : public QWindow
{
public:
    FpsDecider()
        : gl(0)
        , frameCount(0)
    {
        setSurfaceType(OpenGLSurface);
        QSurfaceFormat format;
#if QT_VERSION >= 0x050300
        format.setSwapInterval(1);
#endif
        setFormat(format);
    }

    void exposeEvent(QExposeEvent *) {
        if (isExposed())
            render();
    }

    bool event(QEvent *e)
    {
        if (e->type() == QEvent::UpdateRequest) {
            render();
            return true;
        }
        return QWindow::event(e);
    }

    void render()
    {
        if (!gl) {
            gl = new QOpenGLContext();
            gl->setFormat(format());
            gl->create();
            timer.start();
        }

        gl->makeCurrent(this);
        QOpenGLFunctions *func = gl->functions();

        if (frameCount == 0) {
#if QT_VERSION >= 0x050300
            qDebug() << "GL_VENDOR:  " << (const char *) func->glGetString(GL_VENDOR);
            qDebug() << "GL_RENDERER:" << (const char *) func->glGetString(GL_RENDERER);
            qDebug() << "GL_VERSION: " << (const char *) func->glGetString(GL_VERSION);
#else
            Q_UNUSED(func);
            qDebug() << "GL_VENDOR:  " << (const char *) glGetString(GL_VENDOR);
            qDebug() << "GL_RENDERER:" << (const char *) glGetString(GL_RENDERER);
            qDebug() << "GL_VERSION: " << (const char *) glGetString(GL_VERSION);
#endif
        }

        ++frameCount;
        int c = frameCount % 2;

#if QT_VERSION >= 0x050300
        func->glClearColor(c, 0, 1 - c, 1);
        func->glClear(GL_COLOR_BUFFER_BIT);
#else
        glClearColor(c, 0, 1 - c, 1);
        glClear(GL_COLOR_BUFFER_BIT);
#endif

        gl->swapBuffers(this);

        int time = timer.elapsed();
        if (time > 5000) {
            qDebug() << endl
                     << "FPS:" << frameCount * 1000 / float(time)
                     << " -- " << frameCount << "frames in" << time << "ms;"
                     << time / float(frameCount) << "ms/frame" << endl;
            exit(0);

        } else {
            QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
        }
    }

private:
    QOpenGLContext *gl;
    QElapsedTimer timer;
    int frameCount;
};

struct Options
{
    Options()
        : fullscreen(false)
        , verbose(false)
        , repeat(1)
        , delayedStart(0)
        , fpsTolerance(0.05)
        , fpsInterval(1000)
        , fpsOverride(0)
        , windowSize(800, 600)
    {
    }

    QString bmTemplate;
    bool fullscreen;
    bool verbose;
    int repeat;
    int delayedStart;
    qreal fpsTolerance;
    qreal fpsInterval;
    qreal fpsOverride;
    qreal targetFps;
    QSize windowSize;
};

struct Benchmark
{
    Benchmark(const QString &file)
        : fileName(file)
        , completed(false)
    {
    }

    QString fileName;
    QSize windowSize;

    bool completed;
    QList<qreal> operationsPerFrame;
};

class BenchmarkRunner : public QObject
{
    Q_OBJECT

    // None of these are strictly constant, but for the sake of one QML run, they are
    // so flag it for simplicity
    Q_PROPERTY(QQuickView *view READ view CONSTANT)
    Q_PROPERTY(QQmlComponent *component READ component CONSTANT)
    Q_PROPERTY(qreal screeRefreshRate READ screenRefreshRate CONSTANT)
    Q_PROPERTY(QString input READ input CONSTANT)
    Q_PROPERTY(qreal fpsTolerance READ fpsTolerance CONSTANT)
    Q_PROPERTY(qreal fpsInterval READ fpsInterval CONSTANT)
    Q_PROPERTY(bool verbose READ verbose CONSTANT)

public:
    BenchmarkRunner();
    ~BenchmarkRunner();

    bool execute();

    QList<Benchmark> benchmarks;
    Options options;

    QQuickView *view() const { return m_view; }
    QQmlComponent *component() const { return m_component; }
    qreal screenRefreshRate() const { return options.fpsOverride > 0 ? options.fpsOverride : m_view->screen()->refreshRate(); }
    QString input() const { return benchmarks[m_currentBenchmark].fileName; }

    qreal fpsTolerance() const { return options.fpsTolerance / 100.0; }
    qreal fpsInterval() const { return options.fpsInterval; }

    bool verbose() const { return options.verbose; }

public slots:
    void recordOperationsPerFrame(qreal count);
    void complete();
    void abort();

private slots:
    void start();
    void maybeStartNext();

private:
    void abortAll();

    int m_currentBenchmark;

    QQuickView *m_view;
    QQmlComponent *m_component;
};

int main(int argc, char **argv)
{
    qmlRegisterType<QQuickView>();

	QGuiApplication app(argc, argv);

	QCommandLineParser parser;

    QCommandLineOption decideFpsOption(QStringLiteral("decide-fps"), QStringLiteral("Run a simple test to decide the frame rate of the primary screen"));
    parser.addOption(decideFpsOption);

    QCommandLineOption verboseOption(QStringList() << QStringLiteral("v") << QStringLiteral("verbose"),
                                     QStringLiteral("Verbose mode"));
    parser.addOption(verboseOption);

    QCommandLineOption repeatOption(QStringLiteral("repeat"),
                                         QStringLiteral("Sets the number of times to repeat the benchmark, to get more stable results"),
                                         QStringLiteral("iterations"),
                                         QStringLiteral("1"));
    parser.addOption(repeatOption);

    QCommandLineOption delayOption(QStringLiteral("delay"),
                                   QStringLiteral("Initial delay before benchmarks start"),
                                   QStringLiteral("milliseconds"),
                                   QStringLiteral("0"));
    parser.addOption(delayOption);

    QCommandLineOption widthOption(QStringLiteral("width"),
                                   QStringLiteral("Window Width"),
                                   QStringLiteral("width"),
                                   QStringLiteral("800"));
    parser.addOption(widthOption);

    QCommandLineOption heightOption(QStringLiteral("height"),
                                   QStringLiteral("Window height"),
                                   QStringLiteral("height"),
                                   QStringLiteral("600"));
    parser.addOption(heightOption);

    QCommandLineOption fpsIntervalOption(QStringLiteral("fps-interval"),
                                         QStringLiteral("Set the interval used to measure framerate in ms. Higher values lead to more stable test results"),
                                         QStringLiteral("interval"),
                                         QStringLiteral("1000"));
    parser.addOption(fpsIntervalOption);

    QCommandLineOption fpsToleranceOption(QStringLiteral("fps-tolerance"),
                                          QStringLiteral("The amount of deviance tolerated from the target frame rate in %. Lower value leads to more accurate results"),
                                          QStringLiteral("tolerance"),
                                          QStringLiteral("5"));
    parser.addOption(fpsToleranceOption);

    QCommandLineOption fpsOverrideOption(QStringLiteral("fps-override"),
                                         QStringLiteral("Override QScreen::refreshRate() with a custom refreshrate"),
                                         QStringLiteral("framerate"));
    parser.addOption(fpsOverrideOption);

    QCommandLineOption fullscreenOption(QStringLiteral("fullscreen"), QStringLiteral("Run graphics in fullscreen mode"));
    parser.addOption(fullscreenOption);

    QCommandLineOption templateOption(QStringList() << QStringLiteral("s") << QStringLiteral("shell"),
                                      QStringLiteral("What kind of benchmark shell to run. Available options are: 'sustained-fps'"),
                                      QStringLiteral("template"));
    parser.addOption(templateOption);

    parser.addPositionalArgument(QStringLiteral("input"),
                                 QStringLiteral("One or more QML files or a directory of QML files to benchmark"));
    const QCommandLineOption &helpOption = parser.addHelpOption();

    parser.process(app);

    if (parser.isSet(decideFpsOption)) {
        FpsDecider fpsDecider;
        if (parser.isSet(fullscreenOption))
            fpsDecider.showFullScreen();
        else
            fpsDecider.show();
        fpsDecider.raise();
        return app.exec();
    }

    if (parser.isSet(helpOption) || parser.positionalArguments().size() == 0) {
        parser.showHelp(0);
    }

    BenchmarkRunner runner;
    runner.options.verbose = parser.isSet(verboseOption);
    runner.options.fullscreen = parser.isSet(fullscreenOption);
    runner.options.repeat = qMax<int>(1, parser.value(repeatOption).toInt());
    runner.options.fpsInterval = qMax<qreal>(500, parser.value(fpsIntervalOption).toFloat());
    runner.options.fpsTolerance = qMax<qreal>(1, parser.value(fpsToleranceOption).toFloat());
    runner.options.bmTemplate = parser.value(templateOption);
    runner.options.delayedStart = parser.value(delayOption).toInt();

    QSize size(parser.value(widthOption).toInt(),
               parser.value(heightOption).toInt());

    if (size.isValid())
        runner.options.windowSize = size;

    if (parser.isSet(fpsOverrideOption))
        runner.options.fpsOverride = parser.value(fpsOverrideOption).toFloat();

    if (runner.options.bmTemplate == QStringLiteral("sustained-fps"))
        runner.options.bmTemplate = QStringLiteral("qrc:/Shell_SustainedFpsWithCount.qml");
    else
        runner.options.bmTemplate = QStringLiteral("qrc:/Shell_SustainedFpsWithCount.qml");

    foreach (QString input, parser.positionalArguments()) {
        QFileInfo info(input);
        if (!info.exists()) {
            qDebug() << "input doesn't exist:" << input;
        } else if (info.suffix() == QStringLiteral("qml")) {
            runner.benchmarks << Benchmark(info.absoluteFilePath());
        } else if (info.isDir()) {
            QDirIterator iterator(input, QStringList() << QStringLiteral("*.qml"));
            while (iterator.hasNext()) {
                runner.benchmarks << Benchmark(iterator.next());
            }
        }
    }

    if (runner.options.verbose) {
        qDebug() << "Frame Rate .........:" << (runner.options.fpsOverride > 0 ? runner.options.fpsOverride : QGuiApplication::primaryScreen()->refreshRate());
        qDebug() << "Fullscreen .........:" << (runner.options.fullscreen ? "yes" : "no");
        qDebug() << "Fullscreen .........:" << (runner.options.fullscreen ? "yes" : "no");
        qDebug() << "Fps Interval .......:" << runner.options.fpsInterval;
        qDebug() << "Fps Tolerance ......:" << runner.options.fpsTolerance;
        qDebug() << "Template ...........:" << runner.options.bmTemplate;
        qDebug() << "Benchmarks:";
        foreach (const Benchmark &b, runner.benchmarks) {
            qDebug() << " -" << b.fileName;
        }
    }

    if (!runner.execute())
        return 0;

    return app.exec();
}

BenchmarkRunner::BenchmarkRunner()
    : m_currentBenchmark(0)
    , m_view(0)
{
}

BenchmarkRunner::~BenchmarkRunner()
{
    delete m_view;
}

bool BenchmarkRunner::execute()
{
    m_currentBenchmark = 0;
    if (benchmarks.size() == 0)
        return false;
    QTimer::singleShot(options.delayedStart, this, SLOT(start()));

    m_view = new QQuickView();
    // Make sure proper fullscreen is possible on OSX
    m_view->setFlags(Qt::Window
                     | Qt::WindowSystemMenuHint
                     | Qt::WindowTitleHint
                     | Qt::WindowMinMaxButtonsHint
                     | Qt::WindowCloseButtonHint
                     | Qt::WindowFullscreenButtonHint);
    m_view->setResizeMode(QQuickView::SizeRootObjectToView);
    m_view->rootContext()->setContextProperty("benchmark", this);

    m_view->resize(options.windowSize);

    if (options.fullscreen)
        m_view->showFullScreen();
    else
        m_view->show();
    m_view->raise();

    return true;
}

void BenchmarkRunner::start()
{
    Benchmark &bm = benchmarks[m_currentBenchmark];

    if (bm.operationsPerFrame.size() == 0)
        qDebug() << "running:" << bm.fileName;

    m_component = new QQmlComponent(m_view->engine(), bm.fileName);
    if (m_component->status() != QQmlComponent::Ready) {
        qDebug() << "component is not ready" << bm.fileName;
        abort();
        return;
    }

    m_view->setSource(QUrl(options.bmTemplate));
    if (!m_view->rootObject()) {
        qDebug() << "no root object..";
        abortAll();
        return;
    }

    bm.windowSize = m_view->size();
}

void BenchmarkRunner::maybeStartNext()
{

    ++m_currentBenchmark;
    if (m_currentBenchmark < benchmarks.size()) {
        QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
    } else {
        qDebug() << "All done...";
        qApp->quit();
    }
}

void BenchmarkRunner::abort()
{
    maybeStartNext();
}

void BenchmarkRunner::abortAll()
{
    qDebug() << "Aborting all benchmarks...";
    qApp->quit();
}

void BenchmarkRunner::recordOperationsPerFrame(qreal ops)
{
    Benchmark &bm = benchmarks[m_currentBenchmark];
    bm.completed = true;
    bm.operationsPerFrame << ops;
    qDebug() << "    " << ops << "ops/frame";
    if (bm.operationsPerFrame.size() == options.repeat && options.repeat > 1) {
        qreal avg = 0;
        foreach (qreal r, bm.operationsPerFrame) avg += r;
        qDebug() << "    " << (avg / options.repeat) << "ops/frame average";
    }
    complete();
}

void BenchmarkRunner::complete()
{
    m_component->deleteLater();
    m_component = 0;
    if (benchmarks[m_currentBenchmark].operationsPerFrame.size() < options.repeat)
        QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
    else
        QMetaObject::invokeMethod(this, "maybeStartNext", Qt::QueuedConnection);
}

#include "main.moc"
<|endoftext|>


<commit_before>#ifndef ENGINE_HPP
#define ENGINE_HPP
#include <QObject>
#include <QString>
#include <QVariant>
#include <QMap>
#include <QVector>
#include <QSqlRecord>
#include <QSqlDatabase>
#include <QSqlQueryModel>
#include <QSqlField>
#include <QPrinter>
#include "parser.hpp"
#include "processeddb.hpp"
#include "tags/report.hpp"
#include "converters/convertertoqwidget.hpp"

/*! @~russian
@mainpage QtReports
Добро пожаловать в документацию проекта QtReports

@section intro_sec Введение
Хм.

@section install_sec Установка с помощью CMAKE

@subsection step1 Шаг 1: Распаковка проекта.

Скачать проект по ссылке https://github.com/PO-21/QtReports/archive/master.zip.
Распаковать архив в папку QtReports.
(Полный путь к папке QtReports не должен содержать кириллицы)

@subsection step2 Шаг 2: Генерация CMakeLists.

В корневой папке QtReports, где расположен CMakeLists.txt в командной строке запустить команду:

Для Windows:
cmake [CMAKE_PREFIX_PATH="путь к qt"]  -G "MinGW Makefiles" -B./bin -H./

Для Unix:
cmake [CMAKE_PREFIX_PATH="путь к qt"]  -G "Unix Makefiles" -B./bin -H./

Примечание:
При возникновении ошибки "By not providing "FindQt5Widgets.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"Qt5Widgets", but CMake did not find one." необходимо добавить в команду блок [CMAKE_PREFIX_PATH="путь к qt"].

Пример для Windows:
cmake [CMAKE_PREFIX_PATH="C:/Qt/5.5/mingw492_32"]  -G "MinGW Makefiles" -B./bin -H./

Пример для Unix:
cmake CMAKE_PREFIX_PATH="/usr/lib/x86_64-linux-gnu/qt5"  -G "Unix Makefiles" -B./bin -H./

@subsection step3 Шаг 3: Компиляция проекта.
Windows:
Запустить команду: mingw32-make -C./bin
Linux:
Запустить команду: make -C ./bin

Exe-файл будет расположен в папке qtreportsviewer

@section use_sec Использование
Подключите библиотеку к проекту с помощью
-lqtreportslib -I/usr/include/qtreportslib
и вперед, навстречу приключениям!

*/

namespace qtreports {
    class Engine : public QObject {
        Q_OBJECT

    public:
        Engine( QObject * parent = Q_NULLPTR );
        Engine( const QString & path, QObject * parent = Q_NULLPTR );
        ~Engine();

        bool    open( const QString & path );
        bool    close();

        bool    setParameters( const QMap< QString, QString > & map );
        bool    setConnection( const QSqlDatabase & connection );
        bool    setDataSource( const QMap <QString, QVector <QVariant> > & columnsSet);
        bool    setQuery( const QString & query );
        bool    addScript( const QString & script );
        bool    setDataModel( const QAbstractItemModel & model );

        bool                createPDF( const QString & path );
        bool                createHTML( const QString & path );//etc.
        const QWidgetPtr	createWidget();
        const QWidgetPtr	createLayout();
        bool                print();

        bool        	    isOpened() const;
        const QString       getLastError() const;

    public:
        bool                                m_isOpened;
        QString                             m_lastError, m_compiledPath;
        detail::ReportPtr                   m_report;
        QStringList                         m_queriesList;
        QVector< QString >                  m_scripts;
        QSqlDatabase                        m_dbConnection;
        QWidgetPtr                          m_printedWidget;
        bool                                m_connectionIsSet;
        bool                                m_dataSourceIsSet;
        QMap <QString, QVector <QVariant> > m_dataSource;
        detail::ProcessedDB                 m_processedDB;

        void                                drawPreview( QPrinter * printer );
        bool                                prepareDB();
        void                                prepareDataSource();
        void                                fillColumnsFromReport();
        void                                executeQueries();
    };
}
#endif // ENGINE_HPP
<commit_msg>Update engine.hpp<commit_after>#ifndef ENGINE_HPP
#define ENGINE_HPP
#include <QObject>
#include <QString>
#include <QVariant>
#include <QMap>
#include <QVector>
#include <QSqlRecord>
#include <QSqlDatabase>
#include <QSqlQueryModel>
#include <QSqlField>
#include <QPrinter>
#include "parser.hpp"
#include "processeddb.hpp"
#include "tags/report.hpp"
#include "converters/convertertoqwidget.hpp"

/*! @~russian
@mainpage QtReports
Добро пожаловать в документацию проекта QtReports

@section intro_sec Введение
Хм.

@section install_sec Установка с помощью CMAKE

@subsection step1 Шаг 1: Распаковка проекта.

Скачать проект по ссылке https://github.com/PO-21/QtReports/archive/master.zip.

Распаковать архив в папку QtReports.

(Полный путь к папке QtReports не должен содержать кириллицы)

@subsection step2 Шаг 2: Генерация CMakeLists.

В корневой папке QtReports, где расположен CMakeLists.txt в командной строке запустить команду:

Для Windows:

cmake [CMAKE_PREFIX_PATH="путь к qt"]  -G "MinGW Makefiles" -B./bin -H./

Для Unix:

cmake [CMAKE_PREFIX_PATH="путь к qt"]  -G "Unix Makefiles" -B./bin -H./

Примечание:

При возникновении ошибки "By not providing "FindQt5Widgets.cmake" in CMAKE_MODULE_PATH this project

has asked CMake to find a package configuration file provided by

"Qt5Widgets", but CMake did not find one." необходимо добавить в команду блок [CMAKE_PREFIX_PATH="путь к qt"].

Пример для Windows:
cmake [CMAKE_PREFIX_PATH="C:/Qt/5.5/mingw492_32"]  -G "MinGW Makefiles" -B./bin -H./

Пример для Unix:

cmake CMAKE_PREFIX_PATH="/usr/lib/x86_64-linux-gnu/qt5"  -G "Unix Makefiles" -B./bin -H./

@subsection step3 Шаг 3: Компиляция проекта.

Windows:

Запустить команду: mingw32-make -C./bin

Linux:

Запустить команду: make -C ./bin

Exe-файл будет расположен в папке qtreportsviewer

@section use_sec Использование
Подключите библиотеку к проекту с помощью
-lqtreportslib -I/usr/include/qtreportslib
и вперед, навстречу приключениям!

*/

namespace qtreports {
    class Engine : public QObject {
        Q_OBJECT

    public:
        Engine( QObject * parent = Q_NULLPTR );
        Engine( const QString & path, QObject * parent = Q_NULLPTR );
        ~Engine();

        bool    open( const QString & path );
        bool    close();

        bool    setParameters( const QMap< QString, QString > & map );
        bool    setConnection( const QSqlDatabase & connection );
        bool    setDataSource( const QMap <QString, QVector <QVariant> > & columnsSet);
        bool    setQuery( const QString & query );
        bool    addScript( const QString & script );
        bool    setDataModel( const QAbstractItemModel & model );

        bool                createPDF( const QString & path );
        bool                createHTML( const QString & path );//etc.
        const QWidgetPtr	createWidget();
        const QWidgetPtr	createLayout();
        bool                print();

        bool        	    isOpened() const;
        const QString       getLastError() const;

    public:
        bool                                m_isOpened;
        QString                             m_lastError, m_compiledPath;
        detail::ReportPtr                   m_report;
        QStringList                         m_queriesList;
        QVector< QString >                  m_scripts;
        QSqlDatabase                        m_dbConnection;
        QWidgetPtr                          m_printedWidget;
        bool                                m_connectionIsSet;
        bool                                m_dataSourceIsSet;
        QMap <QString, QVector <QVariant> > m_dataSource;
        detail::ProcessedDB                 m_processedDB;

        void                                drawPreview( QPrinter * printer );
        bool                                prepareDB();
        void                                prepareDataSource();
        void                                fillColumnsFromReport();
        void                                executeQueries();
    };
}
#endif // ENGINE_HPP
<|endoftext|>


<commit_before>//
// Copyright (C) 2006 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <assert.h>

// APPLICATION INCLUDES
#include "os/OsMsgPool.h"
#include "utl/UtlString.h"
#include "os/OsSysLog.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

   // Default constructor.  model is a message of the single type that
   // will be contained in the pool, and its createCopy virtual method
   // will be used to populate the pool.  The caller disposes of model
OsMsgPool::OsMsgPool(const char* name,
   const OsMsg& model,
   int initialCount,
   int softLimit,
   int hardLimit,
   int increment,
   OsMsgPoolSharing sharing)
: mIncrement(increment), mNext(0)
{
   int i;
   OsMsg* pMsg;
   mpMutex = NULL;
   mCurrentCount = 0;
   mpModel = model.createCopy();
   mpModel->setReusable(TRUE);
   mpModel->setInUse(FALSE);

   mpName = new UtlString((NULL == name) ? "Unknown" : name);

   mInitialCount = (initialCount > 1) ? initialCount : 10;
   mSoftLimit = (mInitialCount > softLimit) ? mInitialCount : softLimit;
   mHardLimit = (mSoftLimit > hardLimit) ? mSoftLimit : hardLimit;

   if (mHardLimit > mInitialCount) {
      assert(mIncrement>0);
      mIncrement = (mIncrement>0) ? mIncrement : 1;
   }

   mpElts = new OsMsg*[mHardLimit];

   for (i=0; i<mHardLimit; i++) mpElts[i] = NULL;

   for (i=0; i<mInitialCount; i++) {
      pMsg = mpModel->createCopy();
      if (NULL != pMsg) {
         pMsg->setReusable(TRUE);
         pMsg->setInUse(FALSE);
         mpElts[i] = pMsg;
         mCurrentCount++;
      }
   }

   if (MULTIPLE_CLIENTS == sharing) {
      mpMutex = new OsMutex(OsMutex::Q_PRIORITY |
                            OsMutex::DELETE_SAFE |
                            OsMutex::INVERSION_SAFE);
      assert(NULL != mpMutex);
   }
}

// Destructor
OsMsgPool::~OsMsgPool()
{
   // Hmmm...
   int i;
   OsMsg* pMsg;

   if (NULL != mpMutex) mpMutex->acquire();
   for (i=0; i<mCurrentCount; i++) {
      pMsg = mpElts[i];
      if (NULL != pMsg) {
         pMsg->setReusable(FALSE);
         if (!pMsg->isMsgInUse()) {
            mpElts[i] = NULL;
            delete pMsg;
         }
      }
   }
   delete[] mpElts;
   mpModel->setReusable(FALSE);
   delete mpModel;
   delete mpMutex;
   delete mpName;
}

/* ============================ MANIPULATORS ============================== */

   // Find and return an available element of the pool, creating more if
   // necessary and permitted.  Return NULL if failure.

OsMsg* OsMsgPool::findFreeMsg()
{
   int i;
   OsMsg* pMsg;
   OsMsg* ret = NULL;

   // If there is a mutex for this pool, acquire it before doing any work.
   if (NULL != mpMutex)
   {
      mpMutex->acquire();
   }

   // Scan mNext through the table looking for a message that is
   // allocated and not in use.
   for (i=0; ((i<mCurrentCount)&&(NULL==ret)); i++)
   {
      // Examine the element.
      pMsg = mpElts[mNext];
      if ((NULL != pMsg) && !pMsg->isMsgInUse())
      {
         pMsg->setInUse(TRUE);
         ret = pMsg;
      }
      // Advance mNext, wrapping around if it reaches mCurrentCount.
      mNext++;
      if (mNext >= mCurrentCount)
      {
         mNext = 0;
      }
   }

   // If no free message was found.
   if (NULL == ret)
   {
      if (mCurrentCount > mSoftLimit)
      {
         if (mSoftLimit <= mHardLimit)
         {
            OsSysLog::add(FAC_KERNEL, PRI_WARNING,
                          "OsMsgPool::FindFreeMsg '%s' queue size (%d) exceeds soft limit (%d)\n",
                          mpName->data(), mCurrentCount, mSoftLimit);
         }
      }

      if (mCurrentCount < mHardLimit)
      {
         int limit;

         mNext = mCurrentCount;
         limit = mCurrentCount + mIncrement;
         if (limit > mHardLimit) limit = mHardLimit;
         // Create the new elements.
         for (i=mCurrentCount; i<limit; i++)
         {
            pMsg = mpModel->createCopy();
            if (NULL != pMsg)
            {
               pMsg->setReusable(TRUE);
               pMsg->setInUse(FALSE);
               mpElts[i] = pMsg;
               mCurrentCount++;
            }
         }

         ret = mpElts[mNext];
         assert(NULL!=ret);

         if ((NULL != ret) && !ret->isMsgInUse())
         {
            ret->setInUse(TRUE);
         }
         mNext++;

         if (mNext >= mCurrentCount)
         {
            mNext = 0;
         }
      }
      else
      {
         if (mSoftLimit <= mHardLimit)
         {
            OsSysLog::add(FAC_KERNEL, PRI_CRIT,
                          "OsMsgPool::FindFreeMsg '%s' queue size (%d) exceeds hard limit (%d)\n",
                          mpName->data(), mCurrentCount, mHardLimit);
         }

         mSoftLimit = mHardLimit + 1;
      }
   }

   // If there is a mutex for this pool, release it.
   if (NULL != mpMutex)
   {
      mpMutex->release();
   }
   return ret;
}

/* ============================ ACCESSORS ================================= */

/* ============================ INQUIRY =================================== */

// Return the number of items in use.
int OsMsgPool::getNoInUse(void)
{
   int i, count;

   if (NULL != mpMutex)
   {
      mpMutex->acquire();
   }

   count = 0;
   for (i=0; i < mCurrentCount; i++)
   {
      if (mpElts[i] != NULL && mpElts[i]->isMsgInUse())
      {
         count++;
      }
   }

   if (NULL != mpMutex)
   {
      mpMutex->release();
   }

   return count;
}

// Return the current soft limit.
int OsMsgPool::getSoftLimit(void)
{
   return mSoftLimit;
}

// Return the current hard limit.
int OsMsgPool::getHardLimit(void)
{
   return mHardLimit;
}

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */
<commit_msg>Bugfix: Release internal mutex before deleting it in OsMsgPool destructor. Under Linux this caused error message on console and may be memory leak.<commit_after>//
// Copyright (C) 2006 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// SYSTEM INCLUDES
#include <assert.h>

// APPLICATION INCLUDES
#include "os/OsMsgPool.h"
#include "utl/UtlString.h"
#include "os/OsSysLog.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

   // Default constructor.  model is a message of the single type that
   // will be contained in the pool, and its createCopy virtual method
   // will be used to populate the pool.  The caller disposes of model
OsMsgPool::OsMsgPool(const char* name,
   const OsMsg& model,
   int initialCount,
   int softLimit,
   int hardLimit,
   int increment,
   OsMsgPoolSharing sharing)
: mIncrement(increment), mNext(0)
{
   int i;
   OsMsg* pMsg;
   mpMutex = NULL;
   mCurrentCount = 0;
   mpModel = model.createCopy();
   mpModel->setReusable(TRUE);
   mpModel->setInUse(FALSE);

   mpName = new UtlString((NULL == name) ? "Unknown" : name);

   mInitialCount = (initialCount > 1) ? initialCount : 10;
   mSoftLimit = (mInitialCount > softLimit) ? mInitialCount : softLimit;
   mHardLimit = (mSoftLimit > hardLimit) ? mSoftLimit : hardLimit;

   if (mHardLimit > mInitialCount) {
      assert(mIncrement>0);
      mIncrement = (mIncrement>0) ? mIncrement : 1;
   }

   mpElts = new OsMsg*[mHardLimit];

   for (i=0; i<mHardLimit; i++) mpElts[i] = NULL;

   for (i=0; i<mInitialCount; i++) {
      pMsg = mpModel->createCopy();
      if (NULL != pMsg) {
         pMsg->setReusable(TRUE);
         pMsg->setInUse(FALSE);
         mpElts[i] = pMsg;
         mCurrentCount++;
      }
   }

   if (MULTIPLE_CLIENTS == sharing) {
      mpMutex = new OsMutex(OsMutex::Q_PRIORITY |
                            OsMutex::DELETE_SAFE |
                            OsMutex::INVERSION_SAFE);
      assert(NULL != mpMutex);
   }
}

// Destructor
OsMsgPool::~OsMsgPool()
{
   // Hmmm...
   int i;
   OsMsg* pMsg;

   if (NULL != mpMutex) mpMutex->acquire();
   for (i=0; i<mCurrentCount; i++) {
      pMsg = mpElts[i];
      if (NULL != pMsg) {
         pMsg->setReusable(FALSE);
         if (!pMsg->isMsgInUse()) {
            mpElts[i] = NULL;
            delete pMsg;
         }
      }
   }
   delete[] mpElts;
   mpModel->setReusable(FALSE);
   delete mpModel;
   delete mpName;
   if (NULL != mpMutex) mpMutex->release();
   delete mpMutex;
}

/* ============================ MANIPULATORS ============================== */

   // Find and return an available element of the pool, creating more if
   // necessary and permitted.  Return NULL if failure.

OsMsg* OsMsgPool::findFreeMsg()
{
   int i;
   OsMsg* pMsg;
   OsMsg* ret = NULL;

   // If there is a mutex for this pool, acquire it before doing any work.
   if (NULL != mpMutex)
   {
      mpMutex->acquire();
   }

   // Scan mNext through the table looking for a message that is
   // allocated and not in use.
   for (i=0; ((i<mCurrentCount)&&(NULL==ret)); i++)
   {
      // Examine the element.
      pMsg = mpElts[mNext];
      if ((NULL != pMsg) && !pMsg->isMsgInUse())
      {
         pMsg->setInUse(TRUE);
         ret = pMsg;
      }
      // Advance mNext, wrapping around if it reaches mCurrentCount.
      mNext++;
      if (mNext >= mCurrentCount)
      {
         mNext = 0;
      }
   }

   // If no free message was found.
   if (NULL == ret)
   {
      if (mCurrentCount > mSoftLimit)
      {
         if (mSoftLimit <= mHardLimit)
         {
            OsSysLog::add(FAC_KERNEL, PRI_WARNING,
                          "OsMsgPool::FindFreeMsg '%s' queue size (%d) exceeds soft limit (%d)\n",
                          mpName->data(), mCurrentCount, mSoftLimit);
         }
      }

      if (mCurrentCount < mHardLimit)
      {
         int limit;

         mNext = mCurrentCount;
         limit = mCurrentCount + mIncrement;
         if (limit > mHardLimit) limit = mHardLimit;
         // Create the new elements.
         for (i=mCurrentCount; i<limit; i++)
         {
            pMsg = mpModel->createCopy();
            if (NULL != pMsg)
            {
               pMsg->setReusable(TRUE);
               pMsg->setInUse(FALSE);
               mpElts[i] = pMsg;
               mCurrentCount++;
            }
         }

         ret = mpElts[mNext];
         assert(NULL!=ret);

         if ((NULL != ret) && !ret->isMsgInUse())
         {
            ret->setInUse(TRUE);
         }
         mNext++;

         if (mNext >= mCurrentCount)
         {
            mNext = 0;
         }
      }
      else
      {
         if (mSoftLimit <= mHardLimit)
         {
            OsSysLog::add(FAC_KERNEL, PRI_CRIT,
                          "OsMsgPool::FindFreeMsg '%s' queue size (%d) exceeds hard limit (%d)\n",
                          mpName->data(), mCurrentCount, mHardLimit);
         }

         mSoftLimit = mHardLimit + 1;
      }
   }

   // If there is a mutex for this pool, release it.
   if (NULL != mpMutex)
   {
      mpMutex->release();
   }
   return ret;
}

/* ============================ ACCESSORS ================================= */

/* ============================ INQUIRY =================================== */

// Return the number of items in use.
int OsMsgPool::getNoInUse(void)
{
   int i, count;

   if (NULL != mpMutex)
   {
      mpMutex->acquire();
   }

   count = 0;
   for (i=0; i < mCurrentCount; i++)
   {
      if (mpElts[i] != NULL && mpElts[i]->isMsgInUse())
      {
         count++;
      }
   }

   if (NULL != mpMutex)
   {
      mpMutex->release();
   }

   return count;
}

// Return the current soft limit.
int OsMsgPool::getSoftLimit(void)
{
   return mSoftLimit;
}

// Return the current hard limit.
int OsMsgPool::getHardLimit(void)
{
   return mHardLimit;
}

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */
<|endoftext|>


<commit_before>/*
    Calendar access for KDE Alarm Daemon.

    This file is part of the KDE alarm daemon.
    Copyright (c) 2001 David Jarvie <software@astrojar.org.uk>

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <kstandarddirs.h>
#include <ksimpleconfig.h>
#include <kio/netaccess.h>
#include <kdebug.h>

#include "adcalendarbase.h"

ADCalendarBase::EventsMap ADCalendarBase::eventsHandled_;

ADCalendarBase::ADCalendarBase(const QString& url, const QCString& appname, Type type)
  : urlString_(url),
    appName_(appname),
    actionType_(type),
    loaded_(false),
    mUnregistered(false)
{
  KConfig cfg( locate( "config", "korganizerrc" ) );
  cfg.setGroup( "Time & Date" );
  QString tz = cfg.readEntry( "TimeZoneId" );
  kdDebug(5900) << "ADCalendarBase(): tz: " << tz << endl;
  setTimeZoneId( cfg.readEntry( "TimeZoneId" ) );
}

/*
 * Load the calendar file.
 */
bool ADCalendarBase::loadFile_(const QCString& appName)
{
  loaded_ = false;
  KURL url(urlString_);
  QString tmpFile;
  if (KIO::NetAccess::download(url, tmpFile))
  {
    kdDebug(5900) << "--- Downloaded to " << tmpFile << endl;
    loaded_ = load(tmpFile);
    KIO::NetAccess::removeTempFile(tmpFile);
    if (!loaded_)
      kdDebug(5900) << "ADCalendarBase::loadFile_(): Error loading calendar file '" << tmpFile << "'\n";
    else
    {
      // Remove all now non-existent events from the handled list
      for (EventsMap::Iterator it = eventsHandled_.begin();  it != eventsHandled_.end();  )
      {
        if (it.data().calendarURL == urlString_  &&  !getEvent(it.key()))
        {
          // Event belonged to this calendar, but can't find it any more
          EventsMap::Iterator i = it;
          ++it;                      // prevent iterator becoming invalid with remove()
          eventsHandled_.remove(i);
        }
        else
          ++it;
      }
    }
  }
  else if (!appName.isEmpty()) {
#if TODO_handle_download_error
    KMessageBox::error(0L, i18n("Cannot download calendar from\n%1.")
                           .arg(url.prettyURL()), appName);
#endif
  }
  return loaded_;
}

void ADCalendarBase::dump() const
{
  kdDebug(5900) << "  <calendar>" << endl;
  kdDebug(5900) << "    <url>" << urlString() << "</url>" << endl;
  kdDebug(5900) << "    <appname>" << appName() << "</appname>" << endl;
  if ( loaded() ) kdDebug(5900) << "    <loaded/>" << endl;
  kdDebug(5900) << "    <actiontype>" << int(actionType()) << "</actiontype>" << endl;
  if (enabled() ) kdDebug(5900) << "    <enabled/>" << endl;
  else kdDebug(5900) << "    <disabled/>" << endl;
  if (available()) kdDebug(5900) << "    <available/>" << endl;
  kdDebug(5900) << "  </calendar>" << endl;
}
<commit_msg>Restrict KOrganizer-specific configuration to KOrganizer client<commit_after>/*
    Calendar access for KDE Alarm Daemon.

    This file is part of the KDE alarm daemon.
    Copyright (c) 2001 David Jarvie <software@astrojar.org.uk>

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <kstandarddirs.h>
#include <ksimpleconfig.h>
#include <kio/netaccess.h>
#include <kdebug.h>

#include "adcalendarbase.h"

ADCalendarBase::EventsMap ADCalendarBase::eventsHandled_;

ADCalendarBase::ADCalendarBase(const QString& url, const QCString& appname, Type type)
  : urlString_(url),
    appName_(appname),
    actionType_(type),
    loaded_(false),
    mUnregistered(false)
{
  if (appName_ == "korganizer")
  {
    KConfig cfg( locate( "config", "korganizerrc" ) );
    cfg.setGroup( "Time & Date" );
    QString tz = cfg.readEntry( "TimeZoneId" );
    kdDebug(5900) << "ADCalendarBase(): tz: " << tz << endl;
    setTimeZoneId( cfg.readEntry( "TimeZoneId" ) );
  }
}

/*
 * Load the calendar file.
 */
bool ADCalendarBase::loadFile_(const QCString& appName)
{
  loaded_ = false;
  KURL url(urlString_);
  QString tmpFile;
  if (KIO::NetAccess::download(url, tmpFile))
  {
    kdDebug(5900) << "--- Downloaded to " << tmpFile << endl;
    loaded_ = load(tmpFile);
    KIO::NetAccess::removeTempFile(tmpFile);
    if (!loaded_)
      kdDebug(5900) << "ADCalendarBase::loadFile_(): Error loading calendar file '" << tmpFile << "'\n";
    else
    {
      // Remove all now non-existent events from the handled list
      for (EventsMap::Iterator it = eventsHandled_.begin();  it != eventsHandled_.end();  )
      {
        if (it.data().calendarURL == urlString_  &&  !getEvent(it.key()))
        {
          // Event belonged to this calendar, but can't find it any more
          EventsMap::Iterator i = it;
          ++it;                      // prevent iterator becoming invalid with remove()
          eventsHandled_.remove(i);
        }
        else
          ++it;
      }
    }
  }
  else if (!appName.isEmpty()) {
#if TODO_handle_download_error
    KMessageBox::error(0L, i18n("Cannot download calendar from\n%1.")
                           .arg(url.prettyURL()), appName);
#endif
  }
  return loaded_;
}

void ADCalendarBase::dump() const
{
  kdDebug(5900) << "  <calendar>" << endl;
  kdDebug(5900) << "    <url>" << urlString() << "</url>" << endl;
  kdDebug(5900) << "    <appname>" << appName() << "</appname>" << endl;
  if ( loaded() ) kdDebug(5900) << "    <loaded/>" << endl;
  kdDebug(5900) << "    <actiontype>" << int(actionType()) << "</actiontype>" << endl;
  if (enabled() ) kdDebug(5900) << "    <enabled/>" << endl;
  else kdDebug(5900) << "    <disabled/>" << endl;
  if (available()) kdDebug(5900) << "    <available/>" << endl;
  kdDebug(5900) << "  </calendar>" << endl;
}
<|endoftext|>