<commit_before>/** \copyright
 * Copyright (c) 2014, Balazs Racz
 * 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.
 *
 * 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.
 *
 * \file Packet.hxx
 *
 * Defines a DCC Packet structure.
 *
 * @author Balazs Racz
 * @date 10 May 2014
 */

#ifndef _DCC_PACKET_HXX_
#define _DCC_PACKET_HXX_

#include <stdint.h>
#include <string.h>

#include "dcc/Address.hxx"

namespace dcc
{

/** Represents a command to be sent to the track driver. Most of the commands
 * are "send packet X", but there are some that are controlling the track
 * booster itself, such as "power off". */
struct Packet
{
    /** Maximum number of payload bytes. */
    static const unsigned MAX_PAYLOAD = 5;
    /** Send this speed step to emergency-stop the locomotive. */
    static const unsigned EMERGENCY_STOP = 0xFFFF;
    /** Send this speed step to switch direction of the locomotive. Only used
     * for marklin-14-step speed commands. */
    static const unsigned CHANGE_DIR = 0xFFFF;

    Packet()
    {
        clear();
    }

    struct DCC_IDLE {};
    Packet(DCC_IDLE i) {
        clear();
        set_dcc_idle();
    }

    void clear()
    {
        memset(this, 0, sizeof(*this));
    }

    struct pkt_t
    {
        // Always 0.
        uint8_t is_pkt : 1;
        // 0: DCC packet, 1: motorola packet.
        uint8_t is_marklin : 1;

        // typically for DCC packets:
        // 1: do NOT append an EC byte to the end of the packet.
        uint8_t skip_ec : 1;
        // 1: send long preamble instead of packet. 0: send normal preamble and
        // pkt.
        uint8_t send_long_preamble : 1;
        // 1: wait for service mode ack and report it back to the host.
        uint8_t sense_ack : 1;
        // The packet will be sent 1 + rept_count times to the wire. default: 0.
        uint8_t rept_count : 2;
        uint8_t reserved : 1;
    };

    struct cmd_t
    {
        // Always 1.
        uint8_t is_pkt : 1;
        // Command identifier.
        uint8_t cmd : 7;
    };

    union
    {
        uint8_t header_raw_data;
        pkt_t packet_header;
        cmd_t command_header;
    };
    /** Specifies the number of used payload bytes. */
    uint8_t dlc;
    /** Packet payload bytes. */
    uint8_t payload[MAX_PAYLOAD];

    /** Returns true if this is a packet, false if it is a command to the
     * track processor. */
    bool IsPacket()
    {
        return packet_header.is_pkt;
    }

    void set_cmd(uint8_t cmd)
    {
        dlc = 0;
        HASSERT(cmd & 1);
        header_raw_data = cmd;
    }

    /** Initializes the packet structure for a regular DCC packet. */
    void start_dcc_packet()
    {
        header_raw_data = 0;
        dlc = 0;
    }

    void add_dcc_address(DccShortAddress address);
    void add_dcc_address(DccLongAddress address);

    /** Adds a speed-and-direction command (dcc baseline command) ot the
     * packet. Speed is maximum 14. This should be called after
     * add_dcc_address. */
    void add_dcc_speed14(bool is_fwd, bool light, unsigned speed);
    template <class A>
    void set_dcc_speed14(A a, bool is_fwd, bool light, unsigned speed)
    {
        add_dcc_address(a);
        add_dcc_speed14(is_fwd, light, speed);
    }

    /** Adds a speed-and-direction command (dcc baseline command) to the
     * packet. Speed is maximum 28. This should be called after
     * add_dcc_address. */
    void add_dcc_speed28(bool is_fwd, unsigned speed);
    template <class A> void set_dcc_speed28(A a, bool is_fwd, unsigned speed)
    {
        add_dcc_address(a);
        add_dcc_speed28(is_fwd, speed);
    }

    /** Adds a speed-and-direction command (dcc extended command) for 128 speed
     * steps to the packet. Speed is maximum 126. This shoudl be called after
     * add_dcc_address. */
    void add_dcc_speed128(bool is_fwd, unsigned speed);
    template <class A> void set_dcc_speed128(A a, bool is_fwd, unsigned speed)
    {
        add_dcc_address(a);
        add_dcc_speed128(is_fwd, speed);
    }

    /** Adds a DCC function group command to the packet. The lowest numbered
     * function is always at bit zero. */
    void add_dcc_function0_4(unsigned values);
    void add_dcc_function5_8(unsigned values);
    void add_dcc_function9_12(unsigned values);
    void add_dcc_function13_20(unsigned values);
    void add_dcc_function21_28(unsigned values);

    /** Appends one byte to the packet payload that represents the XOR checksum
     * for DCC. */
    void add_dcc_checksum();

    /** Creates a DCC idle packet. (Includes the checksum.) */
    void set_dcc_idle();

    /** Creates a DCC reset-all-decoders packet. (Includes the checksum.) */
    void set_dcc_reset_all_decoders();

    /** Sets the packet type to marklin-motorola. Initilizes the packet with 18
     * zero bits. */
    void start_mm_packet();

    /** Sets the address and F0 bits of an MM packet to a specific loco
     * address. */
    void add_mm_address(MMAddress address, bool light);

    /** Sets the packet to a 14-step MM speed-and-light packet. Max value of
     * speed is 14. A special value of speed == CHANGE_DIR will signal
     * direction change. */
    void add_mm_speed(unsigned speed);

    /** Sets the packet to a direction-aware 14-step MM speed-and-light
     * packet. Max value of speed is 14. */
    void add_mm_new_speed(bool is_fwd, unsigned speed);

    /** Creates a speed-and-fn packet for the new MM format.
     * @param fn_num is the function, valid values = 1..4
     * @param is whether the funciton is on or off
     * @param speed is the speed step (0..14). If it is set to emergency stop,
     * then no function packet will be generated.
     */
    void add_mm_new_fn(unsigned fn_num, bool value, unsigned speed);

private:
    /** Sets the speed bits of an MM packet. Clips speed to 15, avoids speed==1
     * and returns the final speed step number. */
    unsigned set_mm_speed_bits(unsigned speed);
};

} // namespace dcc

#endif // _DCC_PACKET_HXX_
<commit_msg>increases max packet size to 6 bytes.<commit_after>/** \copyright
 * Copyright (c) 2014, Balazs Racz
 * 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.
 *
 * 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.
 *
 * \file Packet.hxx
 *
 * Defines a DCC Packet structure.
 *
 * @author Balazs Racz
 * @date 10 May 2014
 */

#ifndef _DCC_PACKET_HXX_
#define _DCC_PACKET_HXX_

#include <stdint.h>
#include <string.h>

#include "dcc/Address.hxx"

namespace dcc
{

/** Represents a command to be sent to the track driver. Most of the commands
 * are "send packet X", but there are some that are controlling the track
 * booster itself, such as "power off". */
struct Packet
{
    /** Maximum number of payload bytes. */
    static const unsigned MAX_PAYLOAD = 6;
    /** Send this speed step to emergency-stop the locomotive. */
    static const unsigned EMERGENCY_STOP = 0xFFFF;
    /** Send this speed step to switch direction of the locomotive. Only used
     * for marklin-14-step speed commands. */
    static const unsigned CHANGE_DIR = 0xFFFF;

    Packet()
    {
        clear();
    }

    struct DCC_IDLE {};
    Packet(DCC_IDLE i) {
        clear();
        set_dcc_idle();
    }

    void clear()
    {
        memset(this, 0, sizeof(*this));
    }

    struct pkt_t
    {
        // Always 0.
        uint8_t is_pkt : 1;
        // 0: DCC packet, 1: motorola packet.
        uint8_t is_marklin : 1;

        // typically for DCC packets:
        // 1: do NOT append an EC byte to the end of the packet.
        uint8_t skip_ec : 1;
        // 1: send long preamble instead of packet. 0: send normal preamble and
        // pkt.
        uint8_t send_long_preamble : 1;
        // 1: wait for service mode ack and report it back to the host.
        uint8_t sense_ack : 1;
        // The packet will be sent 1 + rept_count times to the wire. default: 0.
        uint8_t rept_count : 2;
        uint8_t reserved : 1;
    };

    struct cmd_t
    {
        // Always 1.
        uint8_t is_pkt : 1;
        // Command identifier.
        uint8_t cmd : 7;
    };

    union
    {
        uint8_t header_raw_data;
        pkt_t packet_header;
        cmd_t command_header;
    };
    /** Specifies the number of used payload bytes. */
    uint8_t dlc;
    /** Packet payload bytes. */
    uint8_t payload[MAX_PAYLOAD];

    /** Returns true if this is a packet, false if it is a command to the
     * track processor. */
    bool IsPacket()
    {
        return packet_header.is_pkt;
    }

    void set_cmd(uint8_t cmd)
    {
        dlc = 0;
        HASSERT(cmd & 1);
        header_raw_data = cmd;
    }

    /** Initializes the packet structure for a regular DCC packet. */
    void start_dcc_packet()
    {
        header_raw_data = 0;
        dlc = 0;
    }

    void add_dcc_address(DccShortAddress address);
    void add_dcc_address(DccLongAddress address);

    /** Adds a speed-and-direction command (dcc baseline command) ot the
     * packet. Speed is maximum 14. This should be called after
     * add_dcc_address. */
    void add_dcc_speed14(bool is_fwd, bool light, unsigned speed);
    template <class A>
    void set_dcc_speed14(A a, bool is_fwd, bool light, unsigned speed)
    {
        add_dcc_address(a);
        add_dcc_speed14(is_fwd, light, speed);
    }

    /** Adds a speed-and-direction command (dcc baseline command) to the
     * packet. Speed is maximum 28. This should be called after
     * add_dcc_address. */
    void add_dcc_speed28(bool is_fwd, unsigned speed);
    template <class A> void set_dcc_speed28(A a, bool is_fwd, unsigned speed)
    {
        add_dcc_address(a);
        add_dcc_speed28(is_fwd, speed);
    }

    /** Adds a speed-and-direction command (dcc extended command) for 128 speed
     * steps to the packet. Speed is maximum 126. This shoudl be called after
     * add_dcc_address. */
    void add_dcc_speed128(bool is_fwd, unsigned speed);
    template <class A> void set_dcc_speed128(A a, bool is_fwd, unsigned speed)
    {
        add_dcc_address(a);
        add_dcc_speed128(is_fwd, speed);
    }

    /** Adds a DCC function group command to the packet. The lowest numbered
     * function is always at bit zero. */
    void add_dcc_function0_4(unsigned values);
    void add_dcc_function5_8(unsigned values);
    void add_dcc_function9_12(unsigned values);
    void add_dcc_function13_20(unsigned values);
    void add_dcc_function21_28(unsigned values);

    /** Appends one byte to the packet payload that represents the XOR checksum
     * for DCC. */
    void add_dcc_checksum();

    /** Creates a DCC idle packet. (Includes the checksum.) */
    void set_dcc_idle();

    /** Creates a DCC reset-all-decoders packet. (Includes the checksum.) */
    void set_dcc_reset_all_decoders();

    /** Sets the packet type to marklin-motorola. Initilizes the packet with 18
     * zero bits. */
    void start_mm_packet();

    /** Sets the address and F0 bits of an MM packet to a specific loco
     * address. */
    void add_mm_address(MMAddress address, bool light);

    /** Sets the packet to a 14-step MM speed-and-light packet. Max value of
     * speed is 14. A special value of speed == CHANGE_DIR will signal
     * direction change. */
    void add_mm_speed(unsigned speed);

    /** Sets the packet to a direction-aware 14-step MM speed-and-light
     * packet. Max value of speed is 14. */
    void add_mm_new_speed(bool is_fwd, unsigned speed);

    /** Creates a speed-and-fn packet for the new MM format.
     * @param fn_num is the function, valid values = 1..4
     * @param is whether the funciton is on or off
     * @param speed is the speed step (0..14). If it is set to emergency stop,
     * then no function packet will be generated.
     */
    void add_mm_new_fn(unsigned fn_num, bool value, unsigned speed);

private:
    /** Sets the speed bits of an MM packet. Clips speed to 15, avoids speed==1
     * and returns the final speed step number. */
    unsigned set_mm_speed_bits(unsigned speed);
};

} // namespace dcc

#endif // _DCC_PACKET_HXX_
<|endoftext|>


<commit_before>/* Logger.cpp
 *
 * Kubo Ryosuke
 */

#include "logger/Logger.hpp"
#include "common/Def.hpp"
#include <chrono>
#include <ctime>

namespace sunfish {

std::string LoggerUtil::getIso8601() {
  using namespace std::chrono;
  std::time_t t = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
  std::tm m;
#ifdef WIN32
  gmtime_s(&m, &t);
#else
  gmtime_r(&t, &m);
#endif
  std::string buf(22, '\0');
  std::strftime(&buf[0], 22, "%FT%TZ ", &m);
  return buf;
}

std::mutex Logger::mutex_;
Logger Loggers::error  ("[ERROR]");
Logger Loggers::warning("[WARN] ");
Logger Loggers::info   ("[INFO] ");
Logger Loggers::send   ("[SEND] ");
Logger Loggers::receive("[RECV] ");
#ifndef NDEBUG
Logger Loggers::debug  ("[DEBUG]");
#endif //NDEBUG

} // namespace sunfish
<commit_msg>Fix logger<commit_after>/* Logger.cpp
 *
 * Kubo Ryosuke
 */

#include "logger/Logger.hpp"
#include "common/Def.hpp"
#include <chrono>
#include <ctime>

namespace sunfish {

std::string LoggerUtil::getIso8601() {
  using namespace std::chrono;
  std::time_t t = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
  std::tm m;
#ifdef WIN32
  gmtime_s(&m, &t);
#else
  gmtime_r(&t, &m);
#endif
  char buf[22];
  std::strftime(&buf[0], sizeof(buf), "%FT%TZ ", &m);
  return std::string(buf);
}

std::mutex Logger::mutex_;
Logger Loggers::error  ("[ERROR]");
Logger Loggers::warning("[WARN] ");
Logger Loggers::info   ("[INFO] ");
Logger Loggers::send   ("[SEND] ");
Logger Loggers::receive("[RECV] ");
#ifndef NDEBUG
Logger Loggers::debug  ("[DEBUG]");
#endif //NDEBUG

} // namespace sunfish
<|endoftext|>


<commit_before>// Copyright (c) 2016 ASMlover. 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 ofconditions 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 materialsprovided with the
//    distribution.
//
// 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.
#include <assert.h>
#include "../basic/TLogging.h"
#include "TSocketSupport.h"
#include "TChannel.h"
#include "TPoller.h"
#include "TTimerQueue.h"
#include "TKernWrapper.h"
#include "TEventLoop.h"

namespace tyr { namespace net {

#if defined(TYR_WINDOWS)
__declspec(thread) EventLoop* t_loop_this_thread = nullptr;
#else
__thread EventLoop* t_loop_this_thread = nullptr;
#endif
const int kPollMicroSecond = 10000;

void EventLoop::abort_not_in_loopthread(void) {
  TYRLOG_SYSFATAL << "EventLoop::abort_not_in_loopthread - EventLoop " << this
    << " was created in thread: " << tid_
    << ", current thread id: " << basic::CurrentThread::tid();
}

void EventLoop::handle_read(void) {
  // for waked up
  uint64_t one = 1;
  int n = Kern::read_eventfd(wakeup_fd_, &one, sizeof(one));
  if (n != sizeof(one))
    TYRLOG_ERROR << "EventLoop::handle_read() - reads " << n << " bytes instead of 8";
}

void EventLoop::do_pending_functors(void) {
  std::vector<FunctorCallback> functors;
  calling_pending_functors_ = true;

  {
    basic::MutexGuard guard(mtx_);
    functors.swap(pending_functors_);
  }

  for (auto& fn : functors)
    fn();
  calling_pending_functors_ = false;
}

// ================== PUBLIC ==================

EventLoop::EventLoop(void)
  : tid_(basic::CurrentThread::tid())
  , poller_(new Poller(this))
  , timer_queue_(new TimerQueue(this))
  , wakeup_fd_(Kern::create_eventfd())
  , wakeup_channel_(new Channel(this, wakeup_fd_)) {
  TYRLOG_TRACE << "EventLoop created " << this << " in thread " << tid_;
  if (nullptr != t_loop_this_thread)
    TYRLOG_SYSFATAL << "Another EventLoop " << t_loop_this_thread << " exists in this thread " << tid_;
  else
    t_loop_this_thread = this;

  wakeup_channel_->set_read_callback(std::bind(&EventLoop::handle_read, this));
  wakeup_channel_->enabled_reading();
}

EventLoop::~EventLoop(void) {
  assert(!looping_);
  Kern::close_eventfd(wakeup_fd_);
  t_loop_this_thread = nullptr;
}

void EventLoop::loop(void) {
  assert(!looping_);
  assert_in_loopthread();
  looping_ = true;
  quit_ = false;

  while (!quit_) {
    active_channels_.clear();
    poll_return_time_ = poller_->poll(kPollMicroSecond, &active_channels_);
    for (auto channel : active_channels_)
      channel->handle_event(poll_return_time_);

    do_pending_functors();
  }

  TYRLOG_TRACE << "EventLoop " << this << " stop looping";
  looping_ = false;
}

void EventLoop::quit(void) {
  quit_ = true;
  if (!in_loopthread())
    wakeup();
}

void EventLoop::update_channel(Channel* channel) {
  assert(channel->get_owner_loop() == this);
  assert_in_loopthread();
  poller_->update_channel(channel);
}

void EventLoop::remove_channel(Channel* channel) {
  assert(channel->get_owner_loop() == this);
  assert_in_loopthread();
  poller_->remove_channel(channel);
}

TimerID EventLoop::run_at(basic::Timestamp time, const TimerCallback& fn) {
  return timer_queue_->add_timer(fn, time, 0.0);
}

TimerID EventLoop::run_after(double delay, const TimerCallback& fn) {
  basic::Timestamp time(basic::add_time(basic::Timestamp::now(), delay));
  return run_at(time, fn);
}

TimerID EventLoop::run_every(double interval, const TimerCallback& fn) {
  basic::Timestamp time(basic::add_time(basic::Timestamp::now(), interval));
  return timer_queue_->add_timer(fn, time, interval);
}

void EventLoop::wakeup(void) {
  uint64_t one = 1;
  int n = Kern::write_eventfd(wakeup_fd_, &one, sizeof(one));
  if (n != sizeof(one))
    TYRLOG_ERROR << "EventLoop::wakeup() - writes " << n << " bytes instead of 8";
}

void EventLoop::run_in_loop(const FunctorCallback& cb) {
  if (in_loopthread())
    cb();
  else
    put_in_loop(cb);
}

void EventLoop::put_in_loop(const FunctorCallback& cb) {
  {
    basic::MutexGuard guard(mtx_);
    pending_functors_.push_back(cb);
  }

  if (!in_loopthread() || calling_pending_functors_)
    wakeup();
}

}}
<commit_msg>:construction: chore(eventloop): add ignore sigpipe for event loop<commit_after>// Copyright (c) 2016 ASMlover. 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 ofconditions 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 materialsprovided with the
//    distribution.
//
// 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.
#include <assert.h>
#include "../basic/TLogging.h"
#include "TIgnoreSigPipe.h"
#include "TSocketSupport.h"
#include "TChannel.h"
#include "TPoller.h"
#include "TTimerQueue.h"
#include "TKernWrapper.h"
#include "TEventLoop.h"

namespace tyr { namespace net {

#if defined(TYR_WINDOWS)
__declspec(thread) EventLoop* t_loop_this_thread = nullptr;
#else
__thread EventLoop* t_loop_this_thread = nullptr;
#endif
const int kPollMicroSecond = 10000;

IgnoreSigPipe g_ignore_sigpipe;

void EventLoop::abort_not_in_loopthread(void) {
  TYRLOG_SYSFATAL << "EventLoop::abort_not_in_loopthread - EventLoop " << this
    << " was created in thread: " << tid_
    << ", current thread id: " << basic::CurrentThread::tid();
}

void EventLoop::handle_read(void) {
  // for waked up
  uint64_t one = 1;
  int n = Kern::read_eventfd(wakeup_fd_, &one, sizeof(one));
  if (n != sizeof(one))
    TYRLOG_ERROR << "EventLoop::handle_read() - reads " << n << " bytes instead of 8";
}

void EventLoop::do_pending_functors(void) {
  std::vector<FunctorCallback> functors;
  calling_pending_functors_ = true;

  {
    basic::MutexGuard guard(mtx_);
    functors.swap(pending_functors_);
  }

  for (auto& fn : functors)
    fn();
  calling_pending_functors_ = false;
}

// ================== PUBLIC ==================
EventLoop::EventLoop(void)
  : tid_(basic::CurrentThread::tid())
  , poller_(new Poller(this))
  , timer_queue_(new TimerQueue(this))
  , wakeup_fd_(Kern::create_eventfd())
  , wakeup_channel_(new Channel(this, wakeup_fd_)) {
  TYRLOG_TRACE << "EventLoop created " << this << " in thread " << tid_;
  if (nullptr != t_loop_this_thread)
    TYRLOG_SYSFATAL << "Another EventLoop " << t_loop_this_thread << " exists in this thread " << tid_;
  else
    t_loop_this_thread = this;

  wakeup_channel_->set_read_callback(std::bind(&EventLoop::handle_read, this));
  wakeup_channel_->enabled_reading();
}

EventLoop::~EventLoop(void) {
  assert(!looping_);
  Kern::close_eventfd(wakeup_fd_);
  t_loop_this_thread = nullptr;
}

void EventLoop::loop(void) {
  assert(!looping_);
  assert_in_loopthread();
  looping_ = true;
  quit_ = false;

  while (!quit_) {
    active_channels_.clear();
    poll_return_time_ = poller_->poll(kPollMicroSecond, &active_channels_);
    for (auto channel : active_channels_)
      channel->handle_event(poll_return_time_);

    do_pending_functors();
  }

  TYRLOG_TRACE << "EventLoop " << this << " stop looping";
  looping_ = false;
}

void EventLoop::quit(void) {
  quit_ = true;
  if (!in_loopthread())
    wakeup();
}

void EventLoop::update_channel(Channel* channel) {
  assert(channel->get_owner_loop() == this);
  assert_in_loopthread();
  poller_->update_channel(channel);
}

void EventLoop::remove_channel(Channel* channel) {
  assert(channel->get_owner_loop() == this);
  assert_in_loopthread();
  poller_->remove_channel(channel);
}

TimerID EventLoop::run_at(basic::Timestamp time, const TimerCallback& fn) {
  return timer_queue_->add_timer(fn, time, 0.0);
}

TimerID EventLoop::run_after(double delay, const TimerCallback& fn) {
  basic::Timestamp time(basic::add_time(basic::Timestamp::now(), delay));
  return run_at(time, fn);
}

TimerID EventLoop::run_every(double interval, const TimerCallback& fn) {
  basic::Timestamp time(basic::add_time(basic::Timestamp::now(), interval));
  return timer_queue_->add_timer(fn, time, interval);
}

void EventLoop::wakeup(void) {
  uint64_t one = 1;
  int n = Kern::write_eventfd(wakeup_fd_, &one, sizeof(one));
  if (n != sizeof(one))
    TYRLOG_ERROR << "EventLoop::wakeup() - writes " << n << " bytes instead of 8";
}

void EventLoop::run_in_loop(const FunctorCallback& cb) {
  if (in_loopthread())
    cb();
  else
    put_in_loop(cb);
}

void EventLoop::put_in_loop(const FunctorCallback& cb) {
  {
    basic::MutexGuard guard(mtx_);
    pending_functors_.push_back(cb);
  }

  if (!in_loopthread() || calling_pending_functors_)
    wakeup();
}

}}
<|endoftext|>


<commit_before>#include "dialogs.h"
#include <windows.h>
#include <shlobj.h>

std::string Dialog::select_folder() {
  char selected_folder[MAX_PATH];
  char init_path[MAX_PATH];
  auto title = "Please select a folder";
  selected_folder[0] = 0;
  init_path[0] = 0;

  BROWSEINFOA browse;
  browse.hwndOwner = 0;
  browse.pidlRoot = NULL;
  browse.lpszTitle = title;
  browse.pszDisplayName = init_path;
  browse.ulFlags = 0;
  browse.lpfn = NULL;
  auto result = SHBrowseForFolder(&browse);

  if(result)
     SHGetPathFromIDListA(result, selected_folder);

   std::string dir(selected_folder);
   return dir;
}
/*
std::string Dialog::new_file() {
  return open_dialog("Please create a new file",
            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
            Gtk::FILE_CHOOSER_ACTION_SAVE);
}

std::string Dialog::new_folder() {
  return open_dialog("Please create a new folder",
            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)},
            Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
}

std::string Dialog::select_file() {
  return open_dialog("Please choose a folder",
            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)},
            Gtk::FILE_CHOOSER_ACTION_OPEN);
}

std::string Dialog::save_file() {
  return open_dialog("Please choose a file",
            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)},
            Gtk::FILE_CHOOSER_ACTION_OPEN);
}

*/<commit_msg>Change implementation to Vista and up<commit_after>#include "dialogs.h"
#include <shobjidl.h>
#include <memory>
#include <exception>
#include <singletons.h>

#ifndef check(__fun__)
#define MESSAGE "An error occurred when trying open windows dialog"
#define check(__fun__) auto __hr__ = __fun__; if(FAILED(__hr__)) Singleton::terminal()->print(MESSAGE)
#endif

std::string Dialog::select_folder() {
  IFileOpenDialog *dialog = nullptr;
  check(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog)));
  DWORD options;
  check(dialog->GetOptions(&options));

}
/*
std::string Dialog::new_file() {
  return open_dialog("Please create a new file",
            {std::make_pair("Cancel", Gtk::RESPONSECANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)},
            Gtk::FILE_CHOOSER_ACTION_SAVE);
}

std::string Dialog::new_folder() {
  return open_dialog("Please create a new folder",
            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)},
            Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
}

std::string Dialog::select_file() {
  return open_dialog("Please choose a folder",
            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)},
            Gtk::FILE_CHOOSER_ACTION_OPEN);
}

std::string Dialog::save_file() {
  return open_dialog("Please choose a file",
            {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)},
            Gtk::FILE_CHOOSER_ACTION_OPEN);
}

*/<|endoftext|>


<commit_before>#ifndef __GLOBALS_HPP_INCLUDED
#define __GLOBALS_HPP_INCLUDED

#include "any_value.hpp"

// GCC (at least g++ 4.7.2) and Visual Studio 2015 do support
// setting default values of a struct using C++11 syntax.
// Clang 3.7.0 and Visual Studio 2013 do not support
// setting default values of a struct using C++11 syntax.
// Visual Studio 2013 fails to compile, whereas Clang-compiled
// executable with code with setting default values of a struct
// causes Segmentation fault upon execution of the program.
// Compilers that don't support setting default values of a struct
// are handled by setting the default values in a macro.
// http://stackoverflow.com/questions/16782103/initializing-default-values-in-a-struct/16783513#16783513
#ifdef __clang__
#elif defined(__GNUC__)
#define __STRUCT_DEFAULT_VALUES_ARE_ACCEPTED
#elif defined(_WIN32)
#if (_MSC_VER >= 1900)
#define __STRUCT_DEFAULT_VALUES_ARE_ACCEPTED
#endif
#endif

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLFW
#ifndef __GLFW3_H_INCLUDED
#define __GLFW3_H_INCLUDED
#include <glfw3.h>
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cmath>    // NAN
#include <string>   // std::string
#include <vector>   // std::vector
#include <stdint.h> // uint32_t etc.

#ifndef WINDOW_WIDTH
#define WINDOW_WIDTH (1600.0f)
#endif

#ifndef WINDOW_HEIGHT
#define WINDOW_HEIGHT (900.0f)
#endif

#ifndef ASPECT_RATIO
#define ASPECT_RATIO (WINDOW_WIDTH / WINDOW_HEIGHT)
#endif

#ifndef PI
#define PI 3.14159265359f
#endif

#ifndef EARTH_RADIUS
#define EARTH_RADIUS 6371000.0f
#endif

#ifndef TEXT_SIZE
#define TEXT_SIZE 40
#endif

#ifndef FONT_SIZE
#define FONT_SIZE 16
#endif

#ifndef MAX_FPS
#define MAX_FPS 60
#endif

extern glm::mat4 ProjectionMatrix;
extern glm::mat4 ViewMatrix;
extern glm::vec3 position;
extern GLfloat gravity;
extern bool is_flight_mode_in_use;
extern bool in_help_mode;
extern GLfloat fallSpeed;
extern double horizontalAngle;
extern double verticalAngle;
extern GLfloat initialFoV;
extern double earth_radius;
extern bool hasMouseEverMoved;
extern bool is_invert_mouse_in_use;
extern bool is_key_I_released;
extern bool is_key_F_released;
extern bool is_key_F1_released;
extern bool is_world_loaded;        // no more than one world object can be loaded. TODO: check that no more than one world is loaded!
extern bool is_world_spherical;

extern GLfloat speed;
extern GLfloat turbo_factor;
extern GLfloat twin_turbo_factor;
extern GLfloat mouseSpeed;

extern glm::vec3 camera_position;

namespace model
{
    class World;
    class Shader;
    class Graph;
    class Material;
    class Font;
    class Species;
    class Glyph;
}

typedef struct ShaderStruct
{
    ShaderStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    model::World* parent_pointer; // pointer to the world (draw list).
    std::string vertex_shader;    // filename of vertex shader.
    std::string fragment_shader;  // filename of fragment shader.
} ShaderStruct;

typedef struct MaterialStruct
{
    MaterialStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    model::Shader* parent_pointer;   // pointer to the shader.
    std::string texture_file_format; // type of the texture file. supported file formats so far: `"bmp"`/`"BMP"`, `"dds"`/`"DDS"`.
    std::string texture_filename;    // filename of the model file.
    std::string image_path;
} MaterialStruct;

typedef struct NodeStruct
{
    NodeStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    GLuint nodeID;
    model::Graph* parent_pointer;
    glm::vec3 coordinate_vector;
    std::vector<uint32_t> neighbor_nodeIDs;
} NodeStruct;

typedef struct ObjectStruct
{
    ObjectStruct()
        : species_parent_pointer(nullptr), glyph_parent_pointer(nullptr), original_scale_vector(glm::vec3(1.0f, 1.0f, 1.0f)), rotate_angle(NAN), is_character(false)
    {
        // constructor.
    }
    model::Species* species_parent_pointer; // pointer to the parent species.
    model::Glyph* glyph_parent_pointer;     // pointer to the parent glyph.
    glm::vec3 original_scale_vector; // original scale vector.
    GLfloat rotate_angle;            // rotate angle.
    bool is_character;               // The parent of a character object is a Glyph. The parent of a regular object is a Species.
    glm::vec3 coordinate_vector;     // coordinate vector.
    glm::vec3 rotate_vector;         // rotate vector.
    glm::vec3 translate_vector;      // translate vector.
} ObjectStruct;

typedef struct SpeciesStruct
{
    SpeciesStruct()
        : parent_pointer(nullptr), is_world(false), world_radius(NAN), triangulation_type("bilinear_interpolation")
    {
        // constructor.
    }
    // used for all files (for all species).
    model::Material* parent_pointer;         // pointer to the material object.
    bool is_world;                           // worlds currently do not rotate nor translate.
    double world_radius;                     // radius of sea level in meters. used only for worlds.
    std::string model_file_format;           // type of the model file. supported file formats so far: `"bmp"`/`"BMP"`, `"obj"`/`"OBJ"`.
                                             // TODO: add support for `"SRTM"`.
    std::string model_filename;              // filename of the model file.
    // for `"bmp"` model files.
    std::string color_channel;               // color channel to use for altitude data.

    glm::vec3 light_position;                // light position.
    std::string coordinate_system;           // used only for worlds (`is_world` == `true`). valid values: `"cartesian"`.
                                             // TODO: add support for `"spherical"`. `"spherical"` is used eg. in SRTM heightmaps.
    std::string triangulation_type;
} SpeciesStruct;

#define DEFAULT_VERTEX_SCALING_FACTOR (0.001f)

typedef struct FontStruct
{
    FontStruct()
        : parent_pointer(nullptr), vertex_scaling_factor(DEFAULT_VERTEX_SCALING_FACTOR)
    {
        // constructor.
    }
    // used for all files (for all font).
    model::Material* parent_pointer;        // pointer to the material object.
    GLfloat vertex_scaling_factor;
    std::string font_file_format;           // type of the font file. supported file formats so far: `"svg"`/`"SVG"`.
    std::string font_filename;              // filename of the font file.
} FontStruct;

typedef struct GlyphStruct
{
    GlyphStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    // used for all files (for all glyph).
    model::Font* parent_pointer;             // pointer to the font object.
    glm::vec3 light_position;                // light position.
} GlyphStruct;

typedef struct
{
    GLuint screen_width;
    GLuint screen_height;
    GLuint x;
    GLuint y;
    GLuint text_size;
    GLuint font_size;
    const char* text;
    const char* char_font_texture_file_format;
    const char* horizontal_alignment;
    const char* vertical_alignment;
} PrintingStruct;

typedef struct
{
    double rho;
    double theta;
    double phi;
} SphericalCoordinatesStruct;

typedef struct SphericalWorldStruct
{
    SphericalWorldStruct()
        :SRTM_latitude_step_in_degrees(1.0f/1200.0f), SRTM_longitude_step_in_degrees(1.0f/1200.0f)
    {
        // constructor.
    }
    double southern_latitude;
    double northern_latitude;
    double western_longitude;
    double eastern_longitude;
    double SRTM_latitude_step_in_degrees;
    double SRTM_longitude_step_in_degrees;
} SphericalWorldStruct;

typedef struct TriangulateQuadsStruct
{
    TriangulateQuadsStruct()
        : should_ylikuutio_use_real_texture_coordinates(true)
    {
        // constructor.
    }
    GLuint* input_vertex_pointer;
    uint32_t image_width;
    uint32_t image_height;
    std::string triangulation_type;
    bool should_ylikuutio_use_real_texture_coordinates;
    double sphere_radius;
    SphericalWorldStruct spherical_world_struct;
} TriangulateQuadsStruct;

typedef struct
{
    uint32_t* input_vertex_pointer;
    uint32_t image_width;
    uint32_t image_height;
    bool should_ylikuutio_use_real_texture_coordinates;
} BilinearInterpolationStruct;

typedef struct
{
    uint32_t image_width;
    uint32_t image_height;
    double sphere_radius;
    bool is_bilinear_interpolation_in_use;
    SphericalWorldStruct spherical_world_struct;
} TransformationStruct;

namespace callback_system
{
    class CallbackParameter;
}
typedef AnyValue (*InputParametersToAnyValueCallback)(std::vector<callback_system::CallbackParameter*>);

extern SphericalCoordinatesStruct spherical_position;

#endif
<commit_msg>Reordered `#include` lines (alphabetical order).<commit_after>#ifndef __GLOBALS_HPP_INCLUDED
#define __GLOBALS_HPP_INCLUDED

#include "any_value.hpp"

// GCC (at least g++ 4.7.2) and Visual Studio 2015 do support
// setting default values of a struct using C++11 syntax.
// Clang 3.7.0 and Visual Studio 2013 do not support
// setting default values of a struct using C++11 syntax.
// Visual Studio 2013 fails to compile, whereas Clang-compiled
// executable with code with setting default values of a struct
// causes Segmentation fault upon execution of the program.
// Compilers that don't support setting default values of a struct
// are handled by setting the default values in a macro.
// http://stackoverflow.com/questions/16782103/initializing-default-values-in-a-struct/16783513#16783513
#ifdef __clang__
#elif defined(__GNUC__)
#define __STRUCT_DEFAULT_VALUES_ARE_ACCEPTED
#elif defined(_WIN32)
#if (_MSC_VER >= 1900)
#define __STRUCT_DEFAULT_VALUES_ARE_ACCEPTED
#endif
#endif

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLFW
#ifndef __GLFW3_H_INCLUDED
#define __GLFW3_H_INCLUDED
#include <glfw3.h>
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cmath>    // NAN
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string
#include <vector>   // std::vector

#ifndef WINDOW_WIDTH
#define WINDOW_WIDTH (1600.0f)
#endif

#ifndef WINDOW_HEIGHT
#define WINDOW_HEIGHT (900.0f)
#endif

#ifndef ASPECT_RATIO
#define ASPECT_RATIO (WINDOW_WIDTH / WINDOW_HEIGHT)
#endif

#ifndef PI
#define PI 3.14159265359f
#endif

#ifndef EARTH_RADIUS
#define EARTH_RADIUS 6371000.0f
#endif

#ifndef TEXT_SIZE
#define TEXT_SIZE 40
#endif

#ifndef FONT_SIZE
#define FONT_SIZE 16
#endif

#ifndef MAX_FPS
#define MAX_FPS 60
#endif

extern glm::mat4 ProjectionMatrix;
extern glm::mat4 ViewMatrix;
extern glm::vec3 position;
extern GLfloat gravity;
extern bool is_flight_mode_in_use;
extern bool in_help_mode;
extern GLfloat fallSpeed;
extern double horizontalAngle;
extern double verticalAngle;
extern GLfloat initialFoV;
extern double earth_radius;
extern bool hasMouseEverMoved;
extern bool is_invert_mouse_in_use;
extern bool is_key_I_released;
extern bool is_key_F_released;
extern bool is_key_F1_released;
extern bool is_world_loaded;        // no more than one world object can be loaded. TODO: check that no more than one world is loaded!
extern bool is_world_spherical;

extern GLfloat speed;
extern GLfloat turbo_factor;
extern GLfloat twin_turbo_factor;
extern GLfloat mouseSpeed;

extern glm::vec3 camera_position;

namespace model
{
    class World;
    class Shader;
    class Graph;
    class Material;
    class Font;
    class Species;
    class Glyph;
}

typedef struct ShaderStruct
{
    ShaderStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    model::World* parent_pointer; // pointer to the world (draw list).
    std::string vertex_shader;    // filename of vertex shader.
    std::string fragment_shader;  // filename of fragment shader.
} ShaderStruct;

typedef struct MaterialStruct
{
    MaterialStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    model::Shader* parent_pointer;   // pointer to the shader.
    std::string texture_file_format; // type of the texture file. supported file formats so far: `"bmp"`/`"BMP"`, `"dds"`/`"DDS"`.
    std::string texture_filename;    // filename of the model file.
    std::string image_path;
} MaterialStruct;

typedef struct NodeStruct
{
    NodeStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    GLuint nodeID;
    model::Graph* parent_pointer;
    glm::vec3 coordinate_vector;
    std::vector<uint32_t> neighbor_nodeIDs;
} NodeStruct;

typedef struct ObjectStruct
{
    ObjectStruct()
        : species_parent_pointer(nullptr), glyph_parent_pointer(nullptr), original_scale_vector(glm::vec3(1.0f, 1.0f, 1.0f)), rotate_angle(NAN), is_character(false)
    {
        // constructor.
    }
    model::Species* species_parent_pointer; // pointer to the parent species.
    model::Glyph* glyph_parent_pointer;     // pointer to the parent glyph.
    glm::vec3 original_scale_vector; // original scale vector.
    GLfloat rotate_angle;            // rotate angle.
    bool is_character;               // The parent of a character object is a Glyph. The parent of a regular object is a Species.
    glm::vec3 coordinate_vector;     // coordinate vector.
    glm::vec3 rotate_vector;         // rotate vector.
    glm::vec3 translate_vector;      // translate vector.
} ObjectStruct;

typedef struct SpeciesStruct
{
    SpeciesStruct()
        : parent_pointer(nullptr), is_world(false), world_radius(NAN), triangulation_type("bilinear_interpolation")
    {
        // constructor.
    }
    // used for all files (for all species).
    model::Material* parent_pointer;         // pointer to the material object.
    bool is_world;                           // worlds currently do not rotate nor translate.
    double world_radius;                     // radius of sea level in meters. used only for worlds.
    std::string model_file_format;           // type of the model file. supported file formats so far: `"bmp"`/`"BMP"`, `"obj"`/`"OBJ"`.
                                             // TODO: add support for `"SRTM"`.
    std::string model_filename;              // filename of the model file.
    // for `"bmp"` model files.
    std::string color_channel;               // color channel to use for altitude data.

    glm::vec3 light_position;                // light position.
    std::string coordinate_system;           // used only for worlds (`is_world` == `true`). valid values: `"cartesian"`.
                                             // TODO: add support for `"spherical"`. `"spherical"` is used eg. in SRTM heightmaps.
    std::string triangulation_type;
} SpeciesStruct;

#define DEFAULT_VERTEX_SCALING_FACTOR (0.001f)

typedef struct FontStruct
{
    FontStruct()
        : parent_pointer(nullptr), vertex_scaling_factor(DEFAULT_VERTEX_SCALING_FACTOR)
    {
        // constructor.
    }
    // used for all files (for all font).
    model::Material* parent_pointer;        // pointer to the material object.
    GLfloat vertex_scaling_factor;
    std::string font_file_format;           // type of the font file. supported file formats so far: `"svg"`/`"SVG"`.
    std::string font_filename;              // filename of the font file.
} FontStruct;

typedef struct GlyphStruct
{
    GlyphStruct()
        : parent_pointer(nullptr)
    {
        // constructor.
    }
    // used for all files (for all glyph).
    model::Font* parent_pointer;             // pointer to the font object.
    glm::vec3 light_position;                // light position.
} GlyphStruct;

typedef struct
{
    GLuint screen_width;
    GLuint screen_height;
    GLuint x;
    GLuint y;
    GLuint text_size;
    GLuint font_size;
    const char* text;
    const char* char_font_texture_file_format;
    const char* horizontal_alignment;
    const char* vertical_alignment;
} PrintingStruct;

typedef struct
{
    double rho;
    double theta;
    double phi;
} SphericalCoordinatesStruct;

typedef struct SphericalWorldStruct
{
    SphericalWorldStruct()
        :SRTM_latitude_step_in_degrees(1.0f/1200.0f), SRTM_longitude_step_in_degrees(1.0f/1200.0f)
    {
        // constructor.
    }
    double southern_latitude;
    double northern_latitude;
    double western_longitude;
    double eastern_longitude;
    double SRTM_latitude_step_in_degrees;
    double SRTM_longitude_step_in_degrees;
} SphericalWorldStruct;

typedef struct TriangulateQuadsStruct
{
    TriangulateQuadsStruct()
        : should_ylikuutio_use_real_texture_coordinates(true)
    {
        // constructor.
    }
    GLuint* input_vertex_pointer;
    uint32_t image_width;
    uint32_t image_height;
    std::string triangulation_type;
    bool should_ylikuutio_use_real_texture_coordinates;
    double sphere_radius;
    SphericalWorldStruct spherical_world_struct;
} TriangulateQuadsStruct;

typedef struct
{
    uint32_t* input_vertex_pointer;
    uint32_t image_width;
    uint32_t image_height;
    bool should_ylikuutio_use_real_texture_coordinates;
} BilinearInterpolationStruct;

typedef struct
{
    uint32_t image_width;
    uint32_t image_height;
    double sphere_radius;
    bool is_bilinear_interpolation_in_use;
    SphericalWorldStruct spherical_world_struct;
} TransformationStruct;

namespace callback_system
{
    class CallbackParameter;
}
typedef AnyValue (*InputParametersToAnyValueCallback)(std::vector<callback_system::CallbackParameter*>);

extern SphericalCoordinatesStruct spherical_position;

#endif
<|endoftext|>


<commit_before>/*
Resembla: Word-based Japanese similar sentence search library
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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.
*/

#ifndef RESEMBLA_ELIMINATOR_HPP
#define RESEMBLA_ELIMINATOR_HPP

#include <string>
#include <vector>
#include <map>

#include "string_util.hpp"

namespace resembla {

template<typename string_type, typename bitvector_type = uint64_t>
struct Eliminator
{
    using size_type = typename string_type::size_type;
    using symbol_type = typename string_type::value_type;
    using distance_type = int;

    Eliminator(string_type const& pattern = string_type())
    {
        init(pattern);
    }

    void init(string_type const& pattern)
    {
        this->pattern = pattern;
        if(pattern.empty()){
            return;
        }

        pattern_length = pattern.size();
        block_size = ((pattern_length - 1) >> bit_offset<bitvector_type>()) + 1;
        rest_bits = pattern_length - (block_size - 1) * bit_width<bitvector_type>();
        sink = bitvector_type{1} << (rest_bits - 1);

        constructPM();
        zeroes.resize(block_size, 0);
        work.resize(block_size);

        VP0 = 0;
        for(size_type i = 0; i < rest_bits; ++i){
            VP0 |= bitvector_type{1} << i;
        }
    }

    void operator()(std::vector<string_type>& candidates, size_type k)
    {
        using index_distance = std::pair<size_type, distance_type>;

        // calculate scores
        std::vector<index_distance> work(candidates.size());
        for(size_type i = 0; i < work.size(); ++i){
            work[i].first = i;
            work[i].second = -distance(candidates[i]);
        }

        // sort partially to obtain top-k elements
        std::nth_element(std::begin(work), std::begin(work) + k, std::end(work),
            [](const index_distance& a, const index_distance& b) -> bool{
                return a.second > b.second;
            });

        // ensure that work[i].first < work[j].first if i < j < k
        std::sort(std::begin(work), std::begin(work) + k,
            [](const index_distance& a, const index_distance& b) -> bool{
                return a.first < b.first;
            });
#ifdef DEBUG
        std::cerr << "narrow " << work.size() << " strings" << std::endl;
        for(size_type i = 0; i < k; ++i){
            std::cerr << cast_string<std::string>(candidates[work[i].first]) << ": " << work[i].second << std::endl;
        }
#endif

        // sort original list
        for(size_type i = 0; i < k; ++i){
            std::swap(candidates[i], candidates[work[i].first]);
        }
        candidates.erase(std::begin(candidates) + k, std::end(candidates));
    }

protected:
    string_type pattern;
    size_type pattern_length;
    symbol_type c_min, c_max;
    size_type block_size;
    size_type rest_bits;
    bitvector_type sink;

    std::vector<std::pair<symbol_type, std::vector<bitvector_type>>> PM;
    std::vector<bitvector_type> zeroes;

    struct WorkData
    {
        bitvector_type D0;
        bitvector_type HP;
        bitvector_type HN;
        bitvector_type VP;
        bitvector_type VN;

        void reset()
        {
            D0 = HP = HN = VN = 0;
            VP = ~(bitvector_type{0});
        }
    };
    mutable std::vector<WorkData> work;
    bitvector_type VP0;

    template<typename Integer> static constexpr int bit_width()
    {
        return 8 * sizeof(Integer);
    }

    static constexpr int bit_offset(int w)
    {
        return w < 2 ? 0 : (bit_offset(w >> 1) + 1);
    }

    template<typename Integer> static constexpr int bit_offset()
    {
        return bit_offset(bit_width<Integer>());
    }

    template<typename key_type, typename value_type>
    const value_type& find_value(const std::vector<std::pair<key_type, value_type>>& data,
            const key_type c, const value_type& default_value) const
    {
        if(c < c_min || c_max < c){
            return default_value;
        }
        else if(c == c_min){
            return PM.front().second;
        }
        else if(c == c_max){
            return PM.back().second;
        }

        size_type l = 1, r = data.size() - 1;
        while(r - l > 8){
            auto i = (l + r) / 2;
            if(data[i].first < c){
                l = i + 1;
            }
            else if(data[i].first > c){
                r = i;
            }
            else{
                return data[i].second;
            }
        }

        for(size_type i = l; i < r; ++i){
            if(data[i].first == c){
                return data[i].second;
            }
        }

        return default_value;
    }

    void constructPM()
    {
        std::map<symbol_type, std::vector<bitvector_type>> PM_work;
        for(size_type i = 0; i < block_size - 1; ++i){
            for(size_type j = 0; j < bit_width<bitvector_type>(); ++j){
                if(PM_work[pattern[i * bit_width<bitvector_type>() + j]].empty()){
                    PM_work[pattern[i * bit_width<bitvector_type>() + j]].resize(block_size, 0);
                }
                PM_work[pattern[i * bit_width<bitvector_type>() + j]][i] |= bitvector_type{1} << j;
            }
        }
        for(size_type i = 0; i < rest_bits; ++i){
            if(PM_work[pattern[(block_size - 1) * bit_width<bitvector_type>() + i]].empty()){
                PM_work[pattern[(block_size - 1) * bit_width<bitvector_type>() + i]].resize(block_size, 0);
            }
            PM_work[pattern[(block_size - 1) * bit_width<bitvector_type>() + i]].back() |= bitvector_type{1} << i;
        }

        PM.clear();
        for(const auto& p: PM_work){
            PM.push_back(p);
        }
        c_min = PM.front().first;
        c_max = PM.back().first;
    }

    distance_type distance_sp(string_type const &text) const
    {
        auto& w = work.front();
        w.reset();
        w.VP = VP0;

        distance_type D = pattern_length;
        for(auto c: text){
            auto X = find_value(PM, c, zeroes).front() | w.VN;

            w.D0 = ((w.VP + (X & w.VP)) ^ w.VP) | X;
            w.HP = w.VN | ~(w.VP | w.D0);
            w.HN = w.VP & w.D0;

            X = (w.HP << 1) | 1;
            w.VP = (w.HN << 1) | ~(X | w.D0);
            w.VN = X & w.D0;

            if(w.HP & sink){
                ++D;
            }
            else if(w.HN & sink){
                --D;
            }
        }
        return D;
    }

    distance_type distance_lp(string_type const &text) const
    {
        constexpr bitvector_type msb = bitvector_type{1} << (bit_width<bitvector_type>() - 1);

        for(auto& w: work){
            w.reset();
        }
        work.back().VP = VP0;

        distance_type D = pattern_length;
        for(auto c: text){
            const auto& PMc = find_value(PM, c, zeroes);
            for(size_type r = 0; r < block_size; ++r){
                auto& w = work[r];
                auto X = PMc[r];
                if(r > 0 && (work[r - 1].HN & msb)){
                    X |= 1;
                }

                w.D0 = ((w.VP + (X & w.VP)) ^ w.VP) | X | w.VN;
                w.HP = w.VN | ~(w.VP | w.D0);
                w.HN = w.VP & w.D0;

                X = w.HP << 1;
                if(r == 0 || work[r - 1].HP & msb){
                    X |= 1;
                }
                w.VP = (w.HN << 1) | ~(X | w.D0);
                if(r > 0 && (work[r - 1].HN & msb)){
                    w.VP |= 1;
                }
                w.VN = X & w.D0;
            }

            if(work.back().HP & sink){
                ++D;
            }
            else if(work.back().HN & sink){
                --D;
            }
        }
        return D;
    }

    distance_type distance(string_type const &text) const
    {
        if(text.empty()){
            return pattern_length;
        }
        else if(pattern_length == 0){
            return text.size();
        }

        if(block_size == 1){
            return distance_sp(text);
        }
        else{
            return distance_lp(text);
        }
    }
};

}
#endif
<commit_msg>handle tie score<commit_after>/*
Resembla: Word-based Japanese similar sentence search library
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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.
*/

#ifndef RESEMBLA_ELIMINATOR_HPP
#define RESEMBLA_ELIMINATOR_HPP

#include <string>
#include <vector>
#include <map>

#include "string_util.hpp"

namespace resembla {

template<typename string_type, typename bitvector_type = uint64_t>
struct Eliminator
{
    using size_type = typename string_type::size_type;
    using symbol_type = typename string_type::value_type;
    using distance_type = int;

    Eliminator(string_type const& pattern = string_type())
    {
        init(pattern);
    }

    void init(string_type const& pattern)
    {
        this->pattern = pattern;
        if(pattern.empty()){
            return;
        }

        pattern_length = pattern.size();
        block_size = ((pattern_length - 1) >> bit_offset<bitvector_type>()) + 1;
        rest_bits = pattern_length - (block_size - 1) * bit_width<bitvector_type>();
        sink = bitvector_type{1} << (rest_bits - 1);

        constructPM();
        zeroes.resize(block_size, 0);
        work.resize(block_size);

        VP0 = 0;
        for(size_type i = 0; i < rest_bits; ++i){
            VP0 |= bitvector_type{1} << i;
        }
    }

    void operator()(std::vector<string_type>& candidates, size_type k, bool keep_tie = true)
    {
        using index_distance = std::pair<size_type, distance_type>;

        // calculate scores
        std::vector<index_distance> work(candidates.size());
        for(size_type i = 0; i < work.size(); ++i){
            work[i].first = i;
            work[i].second = -distance(candidates[i]);
        }

        if(keep_tie){
            // sort partially to obtain top-k elements
            std::nth_element(std::begin(work), std::begin(work) + k, std::end(work),
                [](const index_distance& a, const index_distance& b) -> bool{
                    return a.second > b.second;
                });
        }
        else{
            std::sort(std::begin(work), std::end(work),
                [](const index_distance& a, const index_distance& b) -> bool{
                    return a.second > b.second;
                });
            // expand k so that work[l] < work[k] for all l > k
            while(k < work.size() - 1 && work[k] == work[k + 1]){
                ++k;
            }
        }

        // ensure that work[i].first < work[j].first if i < j < k
        std::sort(std::begin(work), std::begin(work) + k,
            [](const index_distance& a, const index_distance& b) -> bool{
                return a.first < b.first;
            });
#ifdef DEBUG
        std::cerr << "narrow " << work.size() << " strings" << std::endl;
        for(size_type i = 0; i < k; ++i){
            std::cerr << cast_string<std::string>(candidates[work[i].first]) << ": " << work[i].second << std::endl;
        }
#endif

        // sort original list
        for(size_type i = 0; i < k; ++i){
            std::swap(candidates[i], candidates[work[i].first]);
        }
        candidates.erase(std::begin(candidates) + k, std::end(candidates));
    }

protected:
    string_type pattern;
    size_type pattern_length;
    symbol_type c_min, c_max;
    size_type block_size;
    size_type rest_bits;
    bitvector_type sink;

    std::vector<std::pair<symbol_type, std::vector<bitvector_type>>> PM;
    std::vector<bitvector_type> zeroes;

    struct WorkData
    {
        bitvector_type D0;
        bitvector_type HP;
        bitvector_type HN;
        bitvector_type VP;
        bitvector_type VN;

        void reset()
        {
            D0 = HP = HN = VN = 0;
            VP = ~(bitvector_type{0});
        }
    };
    mutable std::vector<WorkData> work;
    bitvector_type VP0;

    template<typename Integer> static constexpr int bit_width()
    {
        return 8 * sizeof(Integer);
    }

    static constexpr int bit_offset(int w)
    {
        return w < 2 ? 0 : (bit_offset(w >> 1) + 1);
    }

    template<typename Integer> static constexpr int bit_offset()
    {
        return bit_offset(bit_width<Integer>());
    }

    template<typename key_type, typename value_type>
    const value_type& find_value(const std::vector<std::pair<key_type, value_type>>& data,
            const key_type c, const value_type& default_value) const
    {
        if(c < c_min || c_max < c){
            return default_value;
        }
        else if(c == c_min){
            return PM.front().second;
        }
        else if(c == c_max){
            return PM.back().second;
        }

        size_type l = 1, r = data.size() - 1;
        while(r - l > 8){
            auto i = (l + r) / 2;
            if(data[i].first < c){
                l = i + 1;
            }
            else if(data[i].first > c){
                r = i;
            }
            else{
                return data[i].second;
            }
        }

        for(size_type i = l; i < r; ++i){
            if(data[i].first == c){
                return data[i].second;
            }
        }

        return default_value;
    }

    void constructPM()
    {
        std::map<symbol_type, std::vector<bitvector_type>> PM_work;
        for(size_type i = 0; i < block_size - 1; ++i){
            for(size_type j = 0; j < bit_width<bitvector_type>(); ++j){
                if(PM_work[pattern[i * bit_width<bitvector_type>() + j]].empty()){
                    PM_work[pattern[i * bit_width<bitvector_type>() + j]].resize(block_size, 0);
                }
                PM_work[pattern[i * bit_width<bitvector_type>() + j]][i] |= bitvector_type{1} << j;
            }
        }
        for(size_type i = 0; i < rest_bits; ++i){
            if(PM_work[pattern[(block_size - 1) * bit_width<bitvector_type>() + i]].empty()){
                PM_work[pattern[(block_size - 1) * bit_width<bitvector_type>() + i]].resize(block_size, 0);
            }
            PM_work[pattern[(block_size - 1) * bit_width<bitvector_type>() + i]].back() |= bitvector_type{1} << i;
        }

        PM.clear();
        for(const auto& p: PM_work){
            PM.push_back(p);
        }
        c_min = PM.front().first;
        c_max = PM.back().first;
    }

    distance_type distance_sp(string_type const &text) const
    {
        auto& w = work.front();
        w.reset();
        w.VP = VP0;

        distance_type D = pattern_length;
        for(auto c: text){
            auto X = find_value(PM, c, zeroes).front() | w.VN;

            w.D0 = ((w.VP + (X & w.VP)) ^ w.VP) | X;
            w.HP = w.VN | ~(w.VP | w.D0);
            w.HN = w.VP & w.D0;

            X = (w.HP << 1) | 1;
            w.VP = (w.HN << 1) | ~(X | w.D0);
            w.VN = X & w.D0;

            if(w.HP & sink){
                ++D;
            }
            else if(w.HN & sink){
                --D;
            }
        }
        return D;
    }

    distance_type distance_lp(string_type const &text) const
    {
        constexpr bitvector_type msb = bitvector_type{1} << (bit_width<bitvector_type>() - 1);

        for(auto& w: work){
            w.reset();
        }
        work.back().VP = VP0;

        distance_type D = pattern_length;
        for(auto c: text){
            const auto& PMc = find_value(PM, c, zeroes);
            for(size_type r = 0; r < block_size; ++r){
                auto& w = work[r];
                auto X = PMc[r];
                if(r > 0 && (work[r - 1].HN & msb)){
                    X |= 1;
                }

                w.D0 = ((w.VP + (X & w.VP)) ^ w.VP) | X | w.VN;
                w.HP = w.VN | ~(w.VP | w.D0);
                w.HN = w.VP & w.D0;

                X = w.HP << 1;
                if(r == 0 || work[r - 1].HP & msb){
                    X |= 1;
                }
                w.VP = (w.HN << 1) | ~(X | w.D0);
                if(r > 0 && (work[r - 1].HN & msb)){
                    w.VP |= 1;
                }
                w.VN = X & w.D0;
            }

            if(work.back().HP & sink){
                ++D;
            }
            else if(work.back().HN & sink){
                --D;
            }
        }
        return D;
    }

    distance_type distance(string_type const &text) const
    {
        if(text.empty()){
            return pattern_length;
        }
        else if(pattern_length == 0){
            return text.size();
        }

        if(block_size == 1){
            return distance_sp(text);
        }
        else{
            return distance_lp(text);
        }
    }
};

}
#endif
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "media/audio/audio_manager.h"

#include "base/at_exit.h"
#include "base/logging.h"

namespace {

bool g_destroy_called = false;
AudioManager* g_audio_manager = NULL;

// NullAudioManager is the audio manager used on the systems that have no
// audio support.
class NullAudioManager : public AudioManager {
 public:
  NullAudioManager() { }

  // Implementation of AudioManager.
  virtual bool HasAudioOutputDevices() { return false; }
  virtual bool HasAudioInputDevices() { return false; }
  virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params) {
    NOTIMPLEMENTED();
    return NULL;
  }
  virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
                                                 int samples_per_packet) {
    NOTIMPLEMENTED();
    return NULL;
  }
  virtual void MuteAll() { NOTIMPLEMENTED(); }
  virtual void UnMuteAll() { NOTIMPLEMENTED(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(NullAudioManager);
};

}  // namespace

// static
void AudioManager::Destroy(void* not_used) {
  g_destroy_called = true;

  g_audio_manager->Cleanup();

  AudioManager* audio_manager = g_audio_manager;
  g_audio_manager = NULL;
  delete audio_manager;
}

// static
AudioManager* AudioManager::GetAudioManager() {
  if (!g_audio_manager && !g_destroy_called) {
    g_audio_manager = CreateAudioManager();
    g_audio_manager->Init();
    base::AtExitManager::RegisterCallback(&AudioManager::Destroy, NULL);
  }
  return g_audio_manager;
}
<commit_msg>Override AudioManager::MakeAudioInputStream() in NullAudioManager.<commit_after>// Copyright (c) 2010 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 "media/audio/audio_manager.h"

#include "base/at_exit.h"
#include "base/compiler_specific.h"
#include "base/logging.h"

namespace {

bool g_destroy_called = false;
AudioManager* g_audio_manager = NULL;

// NullAudioManager is the audio manager used on the systems that have no
// audio support.
class NullAudioManager : public AudioManager {
 public:
  NullAudioManager() { }

  // Implementation of AudioManager.
  virtual bool HasAudioOutputDevices() OVERRIDE { return false; }
  virtual bool HasAudioInputDevices() OVERRIDE { return false; }
  virtual AudioOutputStream* MakeAudioOutputStream(
      AudioParameters params) OVERRIDE {
    NOTIMPLEMENTED();
    return NULL;
  }
  virtual AudioInputStream* MakeAudioInputStream(
      AudioParameters params) OVERRIDE {
    NOTIMPLEMENTED();
    return NULL;
  }
  virtual void MuteAll() OVERRIDE { NOTIMPLEMENTED(); }
  virtual void UnMuteAll() OVERRIDE { NOTIMPLEMENTED(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(NullAudioManager);
};

}  // namespace

// static
void AudioManager::Destroy(void* not_used) {
  g_destroy_called = true;

  g_audio_manager->Cleanup();

  AudioManager* audio_manager = g_audio_manager;
  g_audio_manager = NULL;
  delete audio_manager;
}

// static
AudioManager* AudioManager::GetAudioManager() {
  if (!g_audio_manager && !g_destroy_called) {
    g_audio_manager = CreateAudioManager();
    g_audio_manager->Init();
    base::AtExitManager::RegisterCallback(&AudioManager::Destroy, NULL);
  }
  return g_audio_manager;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// mapnik
#include <mapnik/expression.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/expression_node_types.hpp>
#include <mapnik/expression_grammar.hpp>

// boost
#include <boost/spirit/include/qi.hpp>

namespace mapnik
{

expression_ptr parse_expression(std::string const& str)
{
    static const expression_grammar<std::string::const_iterator> g;
    boost::spirit::standard_wide::space_type space;
    auto node = std::make_shared<expr_node>();
    std::string::const_iterator itr = str.begin();
    std::string::const_iterator end = str.end();
    bool r = false;
    try
    {
        r = boost::spirit::qi::phrase_parse(itr, end, g, space, *node);
    }
    catch (std::exception const& ex)
    {
        if (std::string("boost::spirit::qi::expectation_failure") == std::string(ex.what()))
        {
            // no need to show "boost::spirit::qi::expectation_failure" which is a std::runtime_error
            throw config_error("Failed to parse expression: \"" + str + "\"");
        }
        else
        {
            // show "Could not initialize ICU resources" from boost::regex which is a std::runtime_error
            throw config_error(std::string(ex.what()) + " for expression: \"" + str + "\"");
        }
    }
    if (r && itr == end)
    {
        return node;
    }
    else
    {
        throw config_error("Failed to parse expression: \"" + str + "\"");
    }
}

}
<commit_msg>use sequencial catch blocks<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// mapnik
#include <mapnik/expression.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/expression_node_types.hpp>
#include <mapnik/expression_grammar.hpp>

// boost
#include <boost/spirit/include/qi.hpp>

namespace mapnik
{

expression_ptr parse_expression(std::string const& str)
{
    static const expression_grammar<std::string::const_iterator> g;
    boost::spirit::standard_wide::space_type space;
    auto node = std::make_shared<expr_node>();
    std::string::const_iterator itr = str.begin();
    std::string::const_iterator end = str.end();
    bool r = false;
    try
    {
        r = boost::spirit::qi::phrase_parse(itr, end, g, space, *node);
    }
    catch (boost::spirit::qi::expectation_failure<std::string::const_iterator> const& ex)
    {
        // no need to show "boost::spirit::qi::expectation_failure" which is a std::runtime_error
        throw config_error("Failed to parse expression: \"" + str + "\"");
    }
    catch (std::exception const& ex)
    {
        // show "Could not initialize ICU resources" from boost::regex which is a std::runtime_error
        throw config_error(std::string(ex.what()) + " for expression: \"" + str + "\"");
    }
    if (r && itr == end)
    {
        return node;
    }
    else
    {
        throw config_error("Failed to parse expression: \"" + str + "\"");
    }
}

}
<|endoftext|>


<commit_before>// Copyright 2016 Etix Labs
//
// 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 "server.h"
#include <cstdio>
#include <cstdlib>
#include <gst/app/gstappsink.h>
#include <gst/app/gstappsrc.h>
#include <iostream>
#include <string.h>

typedef struct _App App;
struct _App {
  GstElement *videosink;
};
App s_app;

typedef struct {
  App *app;
  GstClockTime timestamp;
} Context;

// Receive data from videosink and push it downstream
static void need_data(GstElement *appsrc, guint unused, Context *ctx) {
  GstFlowReturn ret;
  GstSample *sample =
      gst_app_sink_pull_sample(GST_APP_SINK(ctx->app->videosink));
  if (sample != NULL) {
    GstBuffer *buffer = gst_sample_get_buffer(sample);
    gst_app_src_push_sample(GST_APP_SRC(appsrc), sample);
    gst_sample_unref(sample);
    GST_BUFFER_PTS(buffer) = ctx->timestamp;
    GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, 29);
    ctx->timestamp += GST_BUFFER_DURATION(buffer);
    g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
  }
}

// Configure the media to push properly data
static void media_configure(GstRTSPMediaFactory *factory, GstRTSPMedia *media,
                            App *app) {
  Context *ctx;
  GstElement *pipeline;
  GstElement *appsrc;
  pipeline = gst_rtsp_media_get_element(media);
  appsrc = gst_bin_get_by_name_recurse_up(GST_BIN(pipeline), "mysrc");
  gst_util_set_object_arg(G_OBJECT(appsrc), "format", "time");
  g_object_set(G_OBJECT(appsrc), "max-bytes",
               gst_app_src_get_max_bytes(GST_APP_SRC(appsrc)), NULL);
  ctx = g_new0(Context, 1);
  ctx->app = app;
  ctx->timestamp = 0;
  g_signal_connect(appsrc, "need-data", (GCallback)need_data, ctx);
}

// Bus message handler
gboolean bus_callback(GstBus *bus, GstMessage *msg, gpointer data) {
  GstElement *pipeline = GST_ELEMENT(data);

  switch (GST_MESSAGE_TYPE(msg)) {
  case GST_MESSAGE_EOS: // Catch EOS to reset TS
    if (!gst_element_seek(pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
                          GST_SEEK_TYPE_SET, 1000000000, GST_SEEK_TYPE_NONE,
                          GST_CLOCK_TIME_NONE)) {
      g_message("Seek failed!");
    }
    break;
  default:
    break;
  }
  return TRUE;
}

bool configure_file_input(t_server *serv) {
  // Setup and configuration
  App *app = &s_app;
  GstElement *playbin = gst_element_factory_make("playbin", "play");
  app->videosink = gst_element_factory_make("appsink", "video_sink");
  g_object_set(G_OBJECT(app->videosink), "emit-signals", FALSE, "sync", TRUE,
               NULL);
  g_object_set(G_OBJECT(playbin), "video-sink", app->videosink, NULL);
  GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(playbin));
  gst_bus_add_watch(bus, bus_callback, playbin);
  std::string input_path = "file:///" + serv->config->input;
  g_object_set(G_OBJECT(playbin), "uri", input_path.c_str(), NULL);
  gst_element_set_state(playbin, GST_STATE_PLAYING);

  // Media
  g_signal_connect(serv->factory, "media-configure", (GCallback)media_configure,
                   app);

  if (access(input_path.c_str(), F_OK) != -1) {
    return true;
  }
  return false;
}
<commit_msg>Fix incorrect behavior of file_exists checkup when working with docker volumes.<commit_after>// Copyright 2016 Etix Labs
//
// 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 "server.h"
#include <cstdio>
#include <cstdlib>
#include <gst/app/gstappsink.h>
#include <gst/app/gstappsrc.h>
#include <iostream>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

typedef struct _App App;
struct _App {
  GstElement *videosink;
};
App s_app;

typedef struct {
  App *app;
  GstClockTime timestamp;
} Context;

// Receive data from videosink and push it downstream
static void need_data(GstElement *appsrc, guint unused, Context *ctx) {
  GstFlowReturn ret;
  GstSample *sample =
      gst_app_sink_pull_sample(GST_APP_SINK(ctx->app->videosink));
  if (sample != NULL) {
    GstBuffer *buffer = gst_sample_get_buffer(sample);
    gst_app_src_push_sample(GST_APP_SRC(appsrc), sample);
    gst_sample_unref(sample);
    GST_BUFFER_PTS(buffer) = ctx->timestamp;
    GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1, GST_SECOND, 29);
    ctx->timestamp += GST_BUFFER_DURATION(buffer);
    g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
  }
}

// Configure the media to push properly data
static void media_configure(GstRTSPMediaFactory *factory, GstRTSPMedia *media,
                            App *app) {
  Context *ctx;
  GstElement *pipeline;
  GstElement *appsrc;
  pipeline = gst_rtsp_media_get_element(media);
  appsrc = gst_bin_get_by_name_recurse_up(GST_BIN(pipeline), "mysrc");
  gst_util_set_object_arg(G_OBJECT(appsrc), "format", "time");
  g_object_set(G_OBJECT(appsrc), "max-bytes",
               gst_app_src_get_max_bytes(GST_APP_SRC(appsrc)), NULL);
  ctx = g_new0(Context, 1);
  ctx->app = app;
  ctx->timestamp = 0;
  g_signal_connect(appsrc, "need-data", (GCallback)need_data, ctx);
}

// Bus message handler
gboolean bus_callback(GstBus *bus, GstMessage *msg, gpointer data) {
  GstElement *pipeline = GST_ELEMENT(data);

  switch (GST_MESSAGE_TYPE(msg)) {
  case GST_MESSAGE_EOS: // Catch EOS to reset TS
    if (!gst_element_seek(pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
                          GST_SEEK_TYPE_SET, 1000000000, GST_SEEK_TYPE_NONE,
                          GST_CLOCK_TIME_NONE)) {
      g_message("Seek failed!");
    }
    break;
  default:
    break;
  }
  return TRUE;
}

inline bool file_exists (const std::string& name) {
  struct stat buffer;
  std::string corrected_name = name.substr(5);
  return (stat (corrected_name.c_str(), &buffer) == 0);
}

bool configure_file_input(t_server *serv) {
  // Setup and configuration
  App *app = &s_app;
  GstElement *playbin = gst_element_factory_make("playbin", "play");
  app->videosink = gst_element_factory_make("appsink", "video_sink");
  g_object_set(G_OBJECT(app->videosink), "emit-signals", FALSE, "sync", TRUE,
               NULL);
  g_object_set(G_OBJECT(playbin), "video-sink", app->videosink, NULL);
  GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(playbin));
  gst_bus_add_watch(bus, bus_callback, playbin);
  std::string input_path = "file:///" + serv->config->input;
  g_object_set(G_OBJECT(playbin), "uri", input_path.c_str(), NULL);
  gst_element_set_state(playbin, GST_STATE_PLAYING);

  // Media
  g_signal_connect(serv->factory, "media-configure", (GCallback)media_configure,
                   app);

  if (file_exists(input_path)) {
    return true;
  }
  else {
    std::cerr << "Can't access " << input_path.c_str() << std::endl;
  }
  return false;
}
<|endoftext|>


<commit_before>#include "spdlog/details/null_mutex.h"
#include "spdlog/async.h"

#include "spdlog/sinks/base_sink-inl.h"
template class spdlog::sinks::base_sink<std::mutex>;
template class spdlog::sinks::base_sink<spdlog::details::null_mutex>;

#include "spdlog/sinks/basic_file_sink-inl.h"
template class spdlog::sinks::basic_file_sink<std::mutex>;
template class spdlog::sinks::basic_file_sink<spdlog::details::null_mutex>;

#include "spdlog/sinks/rotating_file_sink-inl.h"
template class spdlog::sinks::rotating_file_sink<std::mutex>;
template class spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;<commit_msg>Fixed missing includes<commit_after>// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)

#ifndef SPDLOG_COMPILED_LIB
#error Please define SPDLOG_COMPILED_LIB to compile this file.
#endif

#include <mutex>
#include "spdlog/sinks/base_sink.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/details/file_helper-inl.h"
#include "spdlog/sinks/base_sink-inl.h"
template class spdlog::sinks::base_sink<std::mutex>;
template class spdlog::sinks::base_sink<spdlog::details::null_mutex>;

#include "spdlog/sinks/basic_file_sink-inl.h"
template class spdlog::sinks::basic_file_sink<std::mutex>;
template class spdlog::sinks::basic_file_sink<spdlog::details::null_mutex>;

#include "spdlog/sinks/rotating_file_sink-inl.h"
template class spdlog::sinks::rotating_file_sink<std::mutex>;
template class spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;<|endoftext|>


<commit_before>#include "fixed_rand.h"

namespace {

inline int dux_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); }
//inline int dux_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); }
inline int dux_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }

template<class _IntType, class _URNG>
_IntType UniformIntDistribution(_URNG& __g, _IntType a, _IntType b) {
    typedef typename std::conditional<sizeof(_IntType) <= sizeof(uint32_t),
                                            uint32_t, uint64_t>::type _UIntType;
    const _UIntType _Rp = _UIntType(b) - _UIntType(a) + _UIntType(1);
    if (_Rp == 1)
        return a;
    const size_t _Dt = std::numeric_limits<_UIntType>::digits;
    typedef std::__independent_bits_engine<_URNG, _UIntType> _Eng;
    if (_Rp == 0)
        return static_cast<_IntType>(_Eng(__g, _Dt)());
    auto clz = dux_clz(_Rp);
    size_t __w = _Dt - clz - 1;
    if ((_Rp & (std::numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
        ++__w;
    _Eng __e(__g, __w);
    _UIntType __u;
    do
    {
        __u = __e();
    } while (__u >= _Rp);
    return static_cast<_IntType>(__u + a);
}

}

namespace dux {

FRandGenerator::FRandGenerator(uint32_t seed) : rng_(seed) {}

void FRandGenerator::SetSeed(uint32_t seed) {
  rng_.seed(seed);
}

dux::FInt FRandGenerator::RandFInt(dux::FInt min, dux::FInt max) {
  assert(max >= min);
  return dux::FInt::FromRawValue(UniformIntDistribution<int64_t>(rng_, min.raw_value_, max.raw_value_));
}

dux::FVec2 FRandGenerator::RandFVec2(dux::FInt const minX,
                                     dux::FInt const maxX,
                                     dux::FInt const minY,
                                     dux::FInt const maxY) {
  return dux::FVec2(RandFInt(minX, maxX), RandFInt(minY, maxY));
}

uint32_t FRandGenerator::RandUInt32() {
  return rng_();
}

int64_t FRandGenerator::RandInt64(int64_t min, int64_t max) {
  assert(max >= min);
  return UniformIntDistribution<int64_t>(rng_, min, max);
}

int32_t FRandGenerator::RandInt32(int32_t min, int32_t max) {
  assert(max >= min);
  return UniformIntDistribution<int32_t>(rng_, min, max);
}

float FRandGenerator::RandFloat(float max) {
  return std::generate_canonical<double, 12>(rng_) * max;
}

}  // namespace dux
<commit_msg>Stop depending on internal libcpp template.<commit_after>#include "fixed_rand.h"

namespace {

inline int dux_clz(unsigned __x) { return __builtin_clz(__x); }
//inline int dux_clz(unsigned long __x) { return __builtin_clzl(__x); }
inline int dux_clz(unsigned long long __x) { return __builtin_clzll(__x); }

// __independent_bits_engine

template <unsigned long long _Xp, size_t _Rp>
struct __log2_imp
{
    static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp
                                           : __log2_imp<_Xp, _Rp - 1>::value;
};

template <unsigned long long _Xp>
struct __log2_imp<_Xp, 0>
{
    static const size_t value = 0;
};

template <size_t _Rp>
struct __log2_imp<0, _Rp>
{
    static const size_t value = _Rp + 1;
};

template <class _UIntType, _UIntType _Xp>
struct __log2
{
    static const size_t value = __log2_imp<_Xp,
                                         sizeof(_UIntType) * __CHAR_BIT__ - 1>::value;
};

template<class _Engine, class _UIntType>
class __independent_bits_engine
{
public:
    // types
    typedef _UIntType result_type;

private:
    typedef typename _Engine::result_type _Engine_result_type;
    typedef typename std::conditional
        <
            sizeof(_Engine_result_type) <= sizeof(result_type),
                result_type,
                _Engine_result_type
        >::type _Working_result_type;

    _Engine& __e_;
    size_t __w_;
    size_t __w0_;
    size_t __n_;
    size_t __n0_;
    _Working_result_type __y0_;
    _Working_result_type __y1_;
    _Engine_result_type __mask0_;
    _Engine_result_type __mask1_;

    static constexpr const _Working_result_type _Rp = _Engine::max() - _Engine::min() + _Working_result_type(1);
    static constexpr const size_t __m = __log2<_Working_result_type, _Rp>::value;
    static constexpr const size_t _WDt = std::numeric_limits<_Working_result_type>::digits;
    static constexpr const size_t _EDt = std::numeric_limits<_Engine_result_type>::digits;

public:
    // constructors and seeding functions
    __independent_bits_engine(_Engine& __e, size_t __w);

    // generating functions
    result_type operator()() {return __eval(std::integral_constant<bool, _Rp != 0>());}

private:
    result_type __eval(std::false_type);
    result_type __eval(std::true_type);
};

template<class _Engine, class _UIntType>
__independent_bits_engine<_Engine, _UIntType>
    ::__independent_bits_engine(_Engine& __e, size_t __w)
        : __e_(__e),
          __w_(__w)
{
    __n_ = __w_ / __m + (__w_ % __m != 0);
    __w0_ = __w_ / __n_;
    if (_Rp == 0)
        __y0_ = _Rp;
    else if (__w0_ < _WDt)
        __y0_ = (_Rp >> __w0_) << __w0_;
    else
        __y0_ = 0;
    if (_Rp - __y0_ > __y0_ / __n_)
    {
        ++__n_;
        __w0_ = __w_ / __n_;
        if (__w0_ < _WDt)
            __y0_ = (_Rp >> __w0_) << __w0_;
        else
            __y0_ = 0;
    }
    __n0_ = __n_ - __w_ % __n_;
    if (__w0_ < _WDt - 1)
        __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);
    else
        __y1_ = 0;
    __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :
                          _Engine_result_type(0);
    __mask1_ = __w0_ < _EDt - 1 ?
                               _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :
                               _Engine_result_type(~0);
}

template<class _Engine, class _UIntType>
inline
_UIntType
__independent_bits_engine<_Engine, _UIntType>::__eval(std::false_type)
{
    return static_cast<result_type>(__e_() & __mask0_);
}

template<class _Engine, class _UIntType>
_UIntType
__independent_bits_engine<_Engine, _UIntType>::__eval(std::true_type)
{
    const size_t _WRt = std::numeric_limits<result_type>::digits;
    result_type _Sp = 0;
    for (size_t __k = 0; __k < __n0_; ++__k)
    {
        _Engine_result_type __u;
        do
        {
            __u = __e_() - _Engine::min();
        } while (__u >= __y0_);
        if (__w0_ < _WRt)
            _Sp <<= __w0_;
        else
            _Sp = 0;
        _Sp += __u & __mask0_;
    }
    for (size_t __k = __n0_; __k < __n_; ++__k)
    {
        _Engine_result_type __u;
        do
        {
            __u = __e_() - _Engine::min();
        } while (__u >= __y1_);
        if (__w0_ < _WRt - 1)
            _Sp <<= __w0_ + 1;
        else
            _Sp = 0;
        _Sp += __u & __mask1_;
    }
    return _Sp;
}

template<class _IntType, class _URNG>
_IntType UniformIntDistribution(_URNG& __g, _IntType a, _IntType b) {
    typedef typename std::conditional<sizeof(_IntType) <= sizeof(uint32_t),
                                            uint32_t, uint64_t>::type _UIntType;
    const _UIntType _Rp = _UIntType(b) - _UIntType(a) + _UIntType(1);
    if (_Rp == 1)
        return a;
    const size_t _Dt = std::numeric_limits<_UIntType>::digits;
    typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
    if (_Rp == 0)
        return static_cast<_IntType>(_Eng(__g, _Dt)());
    auto clz = dux_clz(_Rp);
    size_t __w = _Dt - clz - 1;
    if ((_Rp & (std::numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
        ++__w;
    _Eng __e(__g, __w);
    _UIntType __u;
    do
    {
        __u = __e();
    } while (__u >= _Rp);
    return static_cast<_IntType>(__u + a);
}

}

namespace dux {

FRandGenerator::FRandGenerator(uint32_t seed) : rng_(seed) {}

void FRandGenerator::SetSeed(uint32_t seed) {
  rng_.seed(seed);
}

dux::FInt FRandGenerator::RandFInt(dux::FInt min, dux::FInt max) {
  assert(max >= min);
  return dux::FInt::FromRawValue(UniformIntDistribution<int64_t>(rng_, min.raw_value_, max.raw_value_));
}

dux::FVec2 FRandGenerator::RandFVec2(dux::FInt const minX,
                                     dux::FInt const maxX,
                                     dux::FInt const minY,
                                     dux::FInt const maxY) {
  return dux::FVec2(RandFInt(minX, maxX), RandFInt(minY, maxY));
}

uint32_t FRandGenerator::RandUInt32() {
  return rng_();
}

int64_t FRandGenerator::RandInt64(int64_t min, int64_t max) {
  assert(max >= min);
  return UniformIntDistribution<int64_t>(rng_, min, max);
}

int32_t FRandGenerator::RandInt32(int32_t min, int32_t max) {
  assert(max >= min);
  return UniformIntDistribution<int32_t>(rng_, min, max);
}

float FRandGenerator::RandFloat(float max) {
  return std::generate_canonical<double, 12>(rng_) * max;
}

}  // namespace dux
<|endoftext|>