Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next
This commit is contained in:
commit
e6a540660d
2
3rdparty/CMakeLists.txt
vendored
2
3rdparty/CMakeLists.txt
vendored
@ -2,8 +2,6 @@ if (NOT SYSTEM_EXPAT)
|
||||
add_subdirectory(expat)
|
||||
endif()
|
||||
|
||||
add_subdirectory(utf8)
|
||||
|
||||
if (ENABLE_DNS AND NOT SYSTEM_UDNS)
|
||||
add_subdirectory(udns)
|
||||
endif()
|
||||
|
17
3rdparty/utf8/CMakeLists.txt
vendored
17
3rdparty/utf8/CMakeLists.txt
vendored
@ -1,17 +0,0 @@
|
||||
include (SimGearComponent)
|
||||
|
||||
set(HEADERS
|
||||
source/utf8.h
|
||||
)
|
||||
|
||||
set(HEADERS_utf8
|
||||
source/utf8/checked.h
|
||||
source/utf8/core.h
|
||||
source/utf8/unchecked.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
)
|
||||
|
||||
simgear_component(utf8 3rdparty/utf8 "${SOURCES}" "${HEADERS}")
|
||||
simgear_component(utf8-internal 3rdparty/utf8/utf8 "" "${HEADERS_utf8}")
|
12
3rdparty/utf8/doc/ReleaseNotes
vendored
12
3rdparty/utf8/doc/ReleaseNotes
vendored
@ -1,12 +0,0 @@
|
||||
utf8 cpp library
|
||||
Release 2.3.4
|
||||
|
||||
A minor bug fix release. Thanks to all who reported bugs.
|
||||
|
||||
Note: Version 2.3.3 contained a regression, and therefore was removed.
|
||||
|
||||
Changes from version 2.3.2
|
||||
- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
|
||||
- Bug fix [36]: replace_invalid() only works with back_inserter
|
||||
|
||||
Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
|
1789
3rdparty/utf8/doc/utf8cpp.html
vendored
1789
3rdparty/utf8/doc/utf8cpp.html
vendored
File diff suppressed because it is too large
Load Diff
34
3rdparty/utf8/source/utf8.h
vendored
34
3rdparty/utf8/source/utf8.h
vendored
@ -1,34 +0,0 @@
|
||||
// Copyright 2006 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include "utf8/checked.h"
|
||||
#include "utf8/unchecked.h"
|
||||
|
||||
#endif // header guard
|
327
3rdparty/utf8/source/utf8/checked.h
vendored
327
3rdparty/utf8/source/utf8/checked.h
vendored
@ -1,327 +0,0 @@
|
||||
// Copyright 2006 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include "core.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
// Base for the exceptions that may be thrown from the library
|
||||
class exception : public ::std::exception {
|
||||
};
|
||||
|
||||
// Exceptions that may be thrown from the library functions.
|
||||
class invalid_code_point : public exception {
|
||||
uint32_t cp;
|
||||
public:
|
||||
invalid_code_point(uint32_t cp) : cp(cp) {}
|
||||
virtual const char* what() const throw() { return "Invalid code point"; }
|
||||
uint32_t code_point() const {return cp;}
|
||||
};
|
||||
|
||||
class invalid_utf8 : public exception {
|
||||
uint8_t u8;
|
||||
public:
|
||||
invalid_utf8 (uint8_t u) : u8(u) {}
|
||||
virtual const char* what() const throw() { return "Invalid UTF-8"; }
|
||||
uint8_t utf8_octet() const {return u8;}
|
||||
};
|
||||
|
||||
class invalid_utf16 : public exception {
|
||||
uint16_t u16;
|
||||
public:
|
||||
invalid_utf16 (uint16_t u) : u16(u) {}
|
||||
virtual const char* what() const throw() { return "Invalid UTF-16"; }
|
||||
uint16_t utf16_word() const {return u16;}
|
||||
};
|
||||
|
||||
class not_enough_room : public exception {
|
||||
public:
|
||||
virtual const char* what() const throw() { return "Not enough space"; }
|
||||
};
|
||||
|
||||
/// The library API - functions intended to be called by the users
|
||||
|
||||
template <typename octet_iterator>
|
||||
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||
{
|
||||
if (!utf8::internal::is_code_point_valid(cp))
|
||||
throw invalid_code_point(cp);
|
||||
|
||||
if (cp < 0x80) // one octet
|
||||
*(result++) = static_cast<uint8_t>(cp);
|
||||
else if (cp < 0x800) { // two octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
else if (cp < 0x10000) { // three octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
else { // four octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename output_iterator>
|
||||
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
|
||||
{
|
||||
while (start != end) {
|
||||
octet_iterator sequence_start = start;
|
||||
internal::utf_error err_code = utf8::internal::validate_next(start, end);
|
||||
switch (err_code) {
|
||||
case internal::UTF8_OK :
|
||||
for (octet_iterator it = sequence_start; it != start; ++it)
|
||||
*out++ = *it;
|
||||
break;
|
||||
case internal::NOT_ENOUGH_ROOM:
|
||||
throw not_enough_room();
|
||||
case internal::INVALID_LEAD:
|
||||
out = utf8::append (replacement, out);
|
||||
++start;
|
||||
break;
|
||||
case internal::INCOMPLETE_SEQUENCE:
|
||||
case internal::OVERLONG_SEQUENCE:
|
||||
case internal::INVALID_CODE_POINT:
|
||||
out = utf8::append (replacement, out);
|
||||
++start;
|
||||
// just one replacement mark for the sequence
|
||||
while (start != end && utf8::internal::is_trail(*start))
|
||||
++start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename output_iterator>
|
||||
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
|
||||
{
|
||||
static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
|
||||
return utf8::replace_invalid(start, end, out, replacement_marker);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t next(octet_iterator& it, octet_iterator end)
|
||||
{
|
||||
uint32_t cp = 0;
|
||||
internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
|
||||
switch (err_code) {
|
||||
case internal::UTF8_OK :
|
||||
break;
|
||||
case internal::NOT_ENOUGH_ROOM :
|
||||
throw not_enough_room();
|
||||
case internal::INVALID_LEAD :
|
||||
case internal::INCOMPLETE_SEQUENCE :
|
||||
case internal::OVERLONG_SEQUENCE :
|
||||
throw invalid_utf8(*it);
|
||||
case internal::INVALID_CODE_POINT :
|
||||
throw invalid_code_point(cp);
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t peek_next(octet_iterator it, octet_iterator end)
|
||||
{
|
||||
return utf8::next(it, end);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t prior(octet_iterator& it, octet_iterator start)
|
||||
{
|
||||
// can't do much if it == start
|
||||
if (it == start)
|
||||
throw not_enough_room();
|
||||
|
||||
octet_iterator end = it;
|
||||
// Go back until we hit either a lead octet or start
|
||||
while (utf8::internal::is_trail(*(--it)))
|
||||
if (it == start)
|
||||
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||
return utf8::peek_next(it, end);
|
||||
}
|
||||
|
||||
/// Deprecated in versions that include "prior"
|
||||
template <typename octet_iterator>
|
||||
uint32_t previous(octet_iterator& it, octet_iterator pass_start)
|
||||
{
|
||||
octet_iterator end = it;
|
||||
while (utf8::internal::is_trail(*(--it)))
|
||||
if (it == pass_start)
|
||||
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||
octet_iterator temp = it;
|
||||
return utf8::next(temp, end);
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename distance_type>
|
||||
void advance (octet_iterator& it, distance_type n, octet_iterator end)
|
||||
{
|
||||
for (distance_type i = 0; i < n; ++i)
|
||||
utf8::next(it, end);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
typename std::iterator_traits<octet_iterator>::difference_type
|
||||
distance (octet_iterator first, octet_iterator last)
|
||||
{
|
||||
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||
for (dist = 0; first < last; ++dist)
|
||||
utf8::next(first, last);
|
||||
return dist;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename octet_iterator>
|
||||
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||
{
|
||||
while (start != end) {
|
||||
uint32_t cp = utf8::internal::mask16(*start++);
|
||||
// Take care of surrogate pairs first
|
||||
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||
if (start != end) {
|
||||
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||
if (utf8::internal::is_trail_surrogate(trail_surrogate))
|
||||
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||
else
|
||||
throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
|
||||
}
|
||||
else
|
||||
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||
|
||||
}
|
||||
// Lone trail surrogate
|
||||
else if (utf8::internal::is_trail_surrogate(cp))
|
||||
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||
|
||||
result = utf8::append(cp, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename octet_iterator>
|
||||
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||
{
|
||||
while (start != end) {
|
||||
uint32_t cp = utf8::next(start, end);
|
||||
if (cp > 0xffff) { //make a surrogate pair
|
||||
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||
}
|
||||
else
|
||||
*result++ = static_cast<uint16_t>(cp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename u32bit_iterator>
|
||||
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||
{
|
||||
while (start != end)
|
||||
result = utf8::append(*(start++), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename u32bit_iterator>
|
||||
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||
{
|
||||
while (start != end)
|
||||
(*result++) = utf8::next(start, end);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// The iterator class
|
||||
template <typename octet_iterator>
|
||||
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||
octet_iterator it;
|
||||
octet_iterator range_start;
|
||||
octet_iterator range_end;
|
||||
public:
|
||||
iterator () {}
|
||||
explicit iterator (const octet_iterator& octet_it,
|
||||
const octet_iterator& range_start,
|
||||
const octet_iterator& range_end) :
|
||||
it(octet_it), range_start(range_start), range_end(range_end)
|
||||
{
|
||||
if (it < range_start || it > range_end)
|
||||
throw std::out_of_range("Invalid utf-8 iterator position");
|
||||
}
|
||||
// the default "big three" are OK
|
||||
octet_iterator base () const { return it; }
|
||||
uint32_t operator * () const
|
||||
{
|
||||
octet_iterator temp = it;
|
||||
return utf8::next(temp, range_end);
|
||||
}
|
||||
bool operator == (const iterator& rhs) const
|
||||
{
|
||||
if (range_start != rhs.range_start || range_end != rhs.range_end)
|
||||
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
|
||||
return (it == rhs.it);
|
||||
}
|
||||
bool operator != (const iterator& rhs) const
|
||||
{
|
||||
return !(operator == (rhs));
|
||||
}
|
||||
iterator& operator ++ ()
|
||||
{
|
||||
utf8::next(it, range_end);
|
||||
return *this;
|
||||
}
|
||||
iterator operator ++ (int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
utf8::next(it, range_end);
|
||||
return temp;
|
||||
}
|
||||
iterator& operator -- ()
|
||||
{
|
||||
utf8::prior(it, range_start);
|
||||
return *this;
|
||||
}
|
||||
iterator operator -- (int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
utf8::prior(it, range_start);
|
||||
return temp;
|
||||
}
|
||||
}; // class iterator
|
||||
|
||||
} // namespace utf8
|
||||
|
||||
#endif //header guard
|
||||
|
||||
|
329
3rdparty/utf8/source/utf8/core.h
vendored
329
3rdparty/utf8/source/utf8/core.h
vendored
@ -1,329 +0,0 @@
|
||||
// Copyright 2006 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
// The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
|
||||
// You may need to change them to match your system.
|
||||
// These typedefs have the same names as ones from cstdint, or boost/cstdint
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
// Helper code - not intended to be directly called by the library users. May be changed at any time
|
||||
namespace internal
|
||||
{
|
||||
// Unicode constants
|
||||
// Leading (high) surrogates: 0xd800 - 0xdbff
|
||||
// Trailing (low) surrogates: 0xdc00 - 0xdfff
|
||||
const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
|
||||
const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
|
||||
const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
|
||||
const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
|
||||
const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
|
||||
const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
|
||||
|
||||
// Maximum valid value for a Unicode code point
|
||||
const uint32_t CODE_POINT_MAX = 0x0010ffffu;
|
||||
|
||||
template<typename octet_type>
|
||||
inline uint8_t mask8(octet_type oc)
|
||||
{
|
||||
return static_cast<uint8_t>(0xff & oc);
|
||||
}
|
||||
template<typename u16_type>
|
||||
inline uint16_t mask16(u16_type oc)
|
||||
{
|
||||
return static_cast<uint16_t>(0xffff & oc);
|
||||
}
|
||||
template<typename octet_type>
|
||||
inline bool is_trail(octet_type oc)
|
||||
{
|
||||
return ((utf8::internal::mask8(oc) >> 6) == 0x2);
|
||||
}
|
||||
|
||||
template <typename u16>
|
||||
inline bool is_lead_surrogate(u16 cp)
|
||||
{
|
||||
return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
|
||||
}
|
||||
|
||||
template <typename u16>
|
||||
inline bool is_trail_surrogate(u16 cp)
|
||||
{
|
||||
return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||
}
|
||||
|
||||
template <typename u16>
|
||||
inline bool is_surrogate(u16 cp)
|
||||
{
|
||||
return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||
}
|
||||
|
||||
template <typename u32>
|
||||
inline bool is_code_point_valid(u32 cp)
|
||||
{
|
||||
return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline typename std::iterator_traits<octet_iterator>::difference_type
|
||||
sequence_length(octet_iterator lead_it)
|
||||
{
|
||||
uint8_t lead = utf8::internal::mask8(*lead_it);
|
||||
if (lead < 0x80)
|
||||
return 1;
|
||||
else if ((lead >> 5) == 0x6)
|
||||
return 2;
|
||||
else if ((lead >> 4) == 0xe)
|
||||
return 3;
|
||||
else if ((lead >> 3) == 0x1e)
|
||||
return 4;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename octet_difference_type>
|
||||
inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
|
||||
{
|
||||
if (cp < 0x80) {
|
||||
if (length != 1)
|
||||
return true;
|
||||
}
|
||||
else if (cp < 0x800) {
|
||||
if (length != 2)
|
||||
return true;
|
||||
}
|
||||
else if (cp < 0x10000) {
|
||||
if (length != 3)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
|
||||
|
||||
/// Helper for get_sequence_x
|
||||
template <typename octet_iterator>
|
||||
utf_error increase_safely(octet_iterator& it, octet_iterator end)
|
||||
{
|
||||
if (++it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
if (!utf8::internal::is_trail(*it))
|
||||
return INCOMPLETE_SEQUENCE;
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
#define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
|
||||
|
||||
/// get_sequence_x functions decode utf-8 sequences of the length x
|
||||
template <typename octet_iterator>
|
||||
utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
code_point = utf8::internal::mask8(*it);
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
code_point = utf8::internal::mask8(*it);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
code_point = utf8::internal::mask8(*it);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point += (*it) & 0x3f;
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
code_point = utf8::internal::mask8(*it);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point += (*it) & 0x3f;
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
#undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
|
||||
|
||||
template <typename octet_iterator>
|
||||
utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
// Save the original value of it so we can go back in case of failure
|
||||
// Of course, it does not make much sense with i.e. stream iterators
|
||||
octet_iterator original_it = it;
|
||||
|
||||
uint32_t cp = 0;
|
||||
// Determine the sequence length based on the lead octet
|
||||
typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
|
||||
const octet_difference_type length = utf8::internal::sequence_length(it);
|
||||
|
||||
// Get trail octets and calculate the code point
|
||||
utf_error err = UTF8_OK;
|
||||
switch (length) {
|
||||
case 0:
|
||||
return INVALID_LEAD;
|
||||
case 1:
|
||||
err = utf8::internal::get_sequence_1(it, end, cp);
|
||||
break;
|
||||
case 2:
|
||||
err = utf8::internal::get_sequence_2(it, end, cp);
|
||||
break;
|
||||
case 3:
|
||||
err = utf8::internal::get_sequence_3(it, end, cp);
|
||||
break;
|
||||
case 4:
|
||||
err = utf8::internal::get_sequence_4(it, end, cp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err == UTF8_OK) {
|
||||
// Decoding succeeded. Now, security checks...
|
||||
if (utf8::internal::is_code_point_valid(cp)) {
|
||||
if (!utf8::internal::is_overlong_sequence(cp, length)){
|
||||
// Passed! Return here.
|
||||
code_point = cp;
|
||||
++it;
|
||||
return UTF8_OK;
|
||||
}
|
||||
else
|
||||
err = OVERLONG_SEQUENCE;
|
||||
}
|
||||
else
|
||||
err = INVALID_CODE_POINT;
|
||||
}
|
||||
|
||||
// Failure branch - restore the original value of the iterator
|
||||
it = original_it;
|
||||
return err;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
|
||||
uint32_t ignored;
|
||||
return utf8::internal::validate_next(it, end, ignored);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// The library API - functions intended to be called by the users
|
||||
|
||||
// Byte order mark
|
||||
const uint8_t bom[] = {0xef, 0xbb, 0xbf};
|
||||
|
||||
template <typename octet_iterator>
|
||||
octet_iterator find_invalid(octet_iterator start, octet_iterator end)
|
||||
{
|
||||
octet_iterator result = start;
|
||||
while (result != end) {
|
||||
utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
|
||||
if (err_code != internal::UTF8_OK)
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline bool is_valid(octet_iterator start, octet_iterator end)
|
||||
{
|
||||
return (utf8::find_invalid(start, end) == end);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline bool starts_with_bom (octet_iterator it, octet_iterator end)
|
||||
{
|
||||
return (
|
||||
((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
|
||||
((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
|
||||
((it != end) && (utf8::internal::mask8(*it)) == bom[2])
|
||||
);
|
||||
}
|
||||
|
||||
//Deprecated in release 2.3
|
||||
template <typename octet_iterator>
|
||||
inline bool is_bom (octet_iterator it)
|
||||
{
|
||||
return (
|
||||
(utf8::internal::mask8(*it++)) == bom[0] &&
|
||||
(utf8::internal::mask8(*it++)) == bom[1] &&
|
||||
(utf8::internal::mask8(*it)) == bom[2]
|
||||
);
|
||||
}
|
||||
} // namespace utf8
|
||||
|
||||
#endif // header guard
|
||||
|
||||
|
228
3rdparty/utf8/source/utf8/unchecked.h
vendored
228
3rdparty/utf8/source/utf8/unchecked.h
vendored
@ -1,228 +0,0 @@
|
||||
// Copyright 2006 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include "core.h"
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
namespace unchecked
|
||||
{
|
||||
template <typename octet_iterator>
|
||||
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||
{
|
||||
if (cp < 0x80) // one octet
|
||||
*(result++) = static_cast<uint8_t>(cp);
|
||||
else if (cp < 0x800) { // two octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
else if (cp < 0x10000) { // three octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
else { // four octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t next(octet_iterator& it)
|
||||
{
|
||||
uint32_t cp = utf8::internal::mask8(*it);
|
||||
typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
|
||||
switch (length) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
it++;
|
||||
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||
break;
|
||||
case 3:
|
||||
++it;
|
||||
cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||
++it;
|
||||
cp += (*it) & 0x3f;
|
||||
break;
|
||||
case 4:
|
||||
++it;
|
||||
cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||
++it;
|
||||
cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||
++it;
|
||||
cp += (*it) & 0x3f;
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
return cp;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t peek_next(octet_iterator it)
|
||||
{
|
||||
return utf8::unchecked::next(it);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t prior(octet_iterator& it)
|
||||
{
|
||||
while (utf8::internal::is_trail(*(--it))) ;
|
||||
octet_iterator temp = it;
|
||||
return utf8::unchecked::next(temp);
|
||||
}
|
||||
|
||||
// Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
|
||||
template <typename octet_iterator>
|
||||
inline uint32_t previous(octet_iterator& it)
|
||||
{
|
||||
return utf8::unchecked::prior(it);
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename distance_type>
|
||||
void advance (octet_iterator& it, distance_type n)
|
||||
{
|
||||
for (distance_type i = 0; i < n; ++i)
|
||||
utf8::unchecked::next(it);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
typename std::iterator_traits<octet_iterator>::difference_type
|
||||
distance (octet_iterator first, octet_iterator last)
|
||||
{
|
||||
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||
for (dist = 0; first < last; ++dist)
|
||||
utf8::unchecked::next(first);
|
||||
return dist;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename octet_iterator>
|
||||
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||
{
|
||||
while (start != end) {
|
||||
uint32_t cp = utf8::internal::mask16(*start++);
|
||||
// Take care of surrogate pairs first
|
||||
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||
}
|
||||
result = utf8::unchecked::append(cp, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename octet_iterator>
|
||||
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||
{
|
||||
while (start < end) {
|
||||
uint32_t cp = utf8::unchecked::next(start);
|
||||
if (cp > 0xffff) { //make a surrogate pair
|
||||
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||
}
|
||||
else
|
||||
*result++ = static_cast<uint16_t>(cp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename u32bit_iterator>
|
||||
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||
{
|
||||
while (start != end)
|
||||
result = utf8::unchecked::append(*(start++), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename u32bit_iterator>
|
||||
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||
{
|
||||
while (start < end)
|
||||
(*result++) = utf8::unchecked::next(start);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// The iterator class
|
||||
template <typename octet_iterator>
|
||||
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||
octet_iterator it;
|
||||
public:
|
||||
iterator () {}
|
||||
explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
|
||||
// the default "big three" are OK
|
||||
octet_iterator base () const { return it; }
|
||||
uint32_t operator * () const
|
||||
{
|
||||
octet_iterator temp = it;
|
||||
return utf8::unchecked::next(temp);
|
||||
}
|
||||
bool operator == (const iterator& rhs) const
|
||||
{
|
||||
return (it == rhs.it);
|
||||
}
|
||||
bool operator != (const iterator& rhs) const
|
||||
{
|
||||
return !(operator == (rhs));
|
||||
}
|
||||
iterator& operator ++ ()
|
||||
{
|
||||
::std::advance(it, utf8::internal::sequence_length(it));
|
||||
return *this;
|
||||
}
|
||||
iterator operator ++ (int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
::std::advance(it, utf8::internal::sequence_length(it));
|
||||
return temp;
|
||||
}
|
||||
iterator& operator -- ()
|
||||
{
|
||||
utf8::unchecked::prior(it);
|
||||
return *this;
|
||||
}
|
||||
iterator operator -- (int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
utf8::unchecked::prior(it);
|
||||
return temp;
|
||||
}
|
||||
}; // class iterator
|
||||
|
||||
} // namespace utf8::unchecked
|
||||
} // namespace utf8
|
||||
|
||||
|
||||
#endif // header guard
|
||||
|
@ -1,13 +0,0 @@
|
||||
Building a SimGear RPM package for Red Hat
|
||||
|
||||
Please see the "package/openSUSE" directory for an
|
||||
example how to build a SimGear RPM package with
|
||||
shared SimGear libraries.
|
||||
|
||||
You may need to adapt the names (exact spelling) of some
|
||||
of the package dependencies in the openSUSE RPM spec,
|
||||
since these may slightly differ for Red Hat.
|
||||
|
||||
(If you have a working and tested Red Hat RPM spec,
|
||||
you're welcome to contribute it to this project.)
|
||||
|
@ -1,23 +0,0 @@
|
||||
Building a SimGear RPM package for openSUSE
|
||||
|
||||
(Last tested with openSUSE 11.4+12.1)
|
||||
|
||||
This directory contains the files which, along with
|
||||
the source code tar files, can be used to build
|
||||
an RPM package targeted at an openSUSE Linux system.
|
||||
|
||||
To build SimGear from source do the following:
|
||||
|
||||
1. obtain simgear-2.8.0.tar.bz2 (adapt version if
|
||||
necessary) and copy it into ~/rpmbuild/SOURCES
|
||||
|
||||
2. look in the BuildRequires section of SimGear.spec
|
||||
and check that all the packages referred to are
|
||||
installed (note, some of these packages may be part
|
||||
of openSUSE's "games" repository).
|
||||
|
||||
3. run 'rpmbuild -ba simgear.spec' and find the RPM
|
||||
build result in ~/rpmbuild/RPMS
|
||||
|
||||
That's all!
|
||||
|
@ -1,63 +0,0 @@
|
||||
Summary: Simulator Construction Gear
|
||||
Name: SimGear
|
||||
Version: 2.8.0
|
||||
Release: 1
|
||||
License: LGPL
|
||||
URL: http://www.flightgear.org
|
||||
Group: Amusements/Games/3D/Simulation
|
||||
Source: http://mirrors.ibiblio.org/pub/mirrors/flightgear/ftp/Source/simgear-%{version}.tar.bz2
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
|
||||
BuildRequires: gcc, gcc-c++, cmake
|
||||
BuildRequires: libopenal1-soft, openal-soft
|
||||
BuildRequires: libOpenSceneGraph-devel >= 3.0
|
||||
BuildRequires: zlib, zlib-devel
|
||||
BuildRequires: libjpeg62, libjpeg62-devel
|
||||
BuildRequires: boost-devel >= 1.37
|
||||
BuildRequires: subversion-devel, libapr1-devel
|
||||
Requires: OpenSceneGraph-plugins >= 3.0
|
||||
|
||||
%description
|
||||
This package contains a tools and libraries useful for constructing
|
||||
simulation and visualization applications such as FlightGear or TerraGear.
|
||||
|
||||
%package devel
|
||||
Group: Development/Libraries/Other
|
||||
Summary: Development header files for SimGear
|
||||
Requires: SimGear = %{version}
|
||||
|
||||
%description devel
|
||||
Development headers and libraries for building applications against SimGear.
|
||||
|
||||
%prep
|
||||
%setup -T -q -n simgear-%{version} -b 0
|
||||
|
||||
%build
|
||||
export CFLAGS="$RPM_OPT_FLAGS"
|
||||
export CXXFLAGS="$RPM_OPT_FLAGS"
|
||||
# build SHARED simgear libraries
|
||||
cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DSIMGEAR_SHARED:BOOL=ON -DENABLE_TESTS:BOOL=OFF -DJPEG_FACTORY:BOOL=ON
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
make DESTDIR=%{buildroot} install
|
||||
|
||||
%post -p /sbin/ldconfig
|
||||
|
||||
%postun -p /sbin/ldconfig
|
||||
|
||||
%files
|
||||
%defattr (-, root, root, -)
|
||||
%doc AUTHORS COPYING ChangeLog NEWS README
|
||||
%{_libdir}/libSimGear*.so.*
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{_includedir}/simgear
|
||||
%{_includedir}/simgear/*
|
||||
%{_libdir}/libSimGear*.so
|
||||
|
||||
%changelog
|
||||
* Mon Jul 02 2012 thorstenb@flightgear.org
|
||||
- Initial version
|
||||
|
@ -387,7 +387,9 @@ namespace canvas
|
||||
OSGUserData* ud =
|
||||
static_cast<OSGUserData*>(_transform->getChild(index)->getUserData());
|
||||
assert(ud);
|
||||
return ud->element;
|
||||
if (ud)
|
||||
return ud->element;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <simgear_config.h>
|
||||
|
||||
#include "KeyboardEvent.hxx"
|
||||
#include "utf8.h"
|
||||
|
||||
#include <osgGA/GUIEventAdapter>
|
||||
|
||||
@ -42,6 +41,7 @@ namespace canvas
|
||||
|
||||
// TODO check Win/Mac keycode for altgr/ISO Level3 Shift
|
||||
const uint32_t KEY_AltGraph = 0xfe03;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
KeyboardEvent::KeyboardEvent():
|
||||
@ -269,10 +269,24 @@ namespace canvas
|
||||
// Empty or no mapping -> convert UTF-32 key value to UTF-8
|
||||
if( _name.empty() )
|
||||
{
|
||||
if( !utf8::internal::is_code_point_valid(_key) )
|
||||
if (( _key >= 0xd800u && _key <= 0xdfffu ) || _key > 0x10ffffu )
|
||||
_name = "Unidentified";
|
||||
else
|
||||
utf8::unchecked::append(_key, std::back_inserter(_name));
|
||||
if ( _key <= 0x7f ) {
|
||||
_name.push_back(static_cast<uint8_t>(_key));
|
||||
} else if ( _key <= 0x7ff ) {
|
||||
_name.push_back(static_cast<uint8_t>((_key >> 6) | 0xc0));
|
||||
_name.push_back(static_cast<uint8_t>((_key & 0x3f) | 0x80));
|
||||
} else if ( _key <= 0xffff ) {
|
||||
_name.push_back(static_cast<uint8_t>((_key >> 12) | 0xe0));
|
||||
_name.push_back(static_cast<uint8_t>(((_key >> 6) & 0x3f) | 0x80));
|
||||
_name.push_back(static_cast<uint8_t>((_key & 0x3f) | 0x80));
|
||||
} else {
|
||||
_name.push_back(static_cast<uint8_t>((_key >> 18) | 0xf0));
|
||||
_name.push_back(static_cast<uint8_t>(((_key >> 12) & 0x3f) | 0x80));
|
||||
_name.push_back(static_cast<uint8_t>(((_key >> 6) & 0x3f) | 0x80));
|
||||
_name.push_back(static_cast<uint8_t>((_key & 0x3f) | 0x80));
|
||||
}
|
||||
}
|
||||
|
||||
// Keys on the numpad with NumLock enabled are reported just like their
|
||||
@ -307,11 +321,30 @@ namespace canvas
|
||||
if( key_name.empty() )
|
||||
return false;
|
||||
|
||||
std::string::const_iterator it = key_name.begin();
|
||||
uint32_t cp = utf8::next(it, key_name.end());
|
||||
// Convert the key name to the corresponding code point by checking the
|
||||
// sequence length (the first bits of the first byte) and performing the
|
||||
// conversion accordingly.
|
||||
uint32_t cp = key_name[0] & 0xff;
|
||||
size_t len;
|
||||
if (cp < 0x80) {
|
||||
len = 1;
|
||||
} else if ((cp >> 5) == 0x6) {
|
||||
cp = ((cp << 6) & 0x7ff) + (key_name[1] & 0x3f);
|
||||
len = 2;
|
||||
} else if ((cp >> 4) == 0xe) {
|
||||
cp = ((cp << 12) & 0xffff) + (((key_name[1] & 0xff) << 6) & 0xfff)
|
||||
+ (key_name[2] & 0x3f);
|
||||
len = 3;
|
||||
} else if ((cp >> 3) == 0x1e) {
|
||||
cp = ((cp << 18) & 0x1fffff) + (((key_name[1] & 0xff) << 12) & 0x3ffff)
|
||||
+ (((key_name[2] & 0xff) << 6) & 0xfff) + (key_name[3] & 0x3f);
|
||||
len = 4;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if _name contains exactly one (UTF-8 encoded) character.
|
||||
if( it != key_name.end() )
|
||||
if (key_name.length() > len)
|
||||
return false;
|
||||
|
||||
// C0 and C1 control characters are not printable.
|
||||
|
@ -45,7 +45,7 @@ namespace canvas
|
||||
//----------------------------------------------------------------------------
|
||||
NasalWidget::~NasalWidget()
|
||||
{
|
||||
onRemove();
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -95,7 +95,7 @@ const float SG_RADIANS_TO_DEGREES = 180.0f / SG_PI;
|
||||
/** Value of earth radius from LaRCsim (ft) */
|
||||
#define SG_EQUATORIAL_RADIUS_FT 20925650.
|
||||
|
||||
/** Value of earth radius from LaRCsim (meter) */
|
||||
/** Value of equatorial earth radius from LaRCsim (meter) */
|
||||
#define SG_EQUATORIAL_RADIUS_M 6378138.12
|
||||
|
||||
/** Radius squared (ft) */
|
||||
@ -104,6 +104,8 @@ const float SG_RADIANS_TO_DEGREES = 180.0f / SG_PI;
|
||||
/** Radius squared (meter) */
|
||||
#define SG_EQ_RAD_SQUARE_M 40680645877797.1344
|
||||
|
||||
/** Value of WGS84 polar earth radius (meter) */
|
||||
#define SG_POLAR_RADIUS_M 6356752.3142451794975639668
|
||||
|
||||
// Physical Constants, SI
|
||||
|
||||
|
@ -38,20 +38,17 @@
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/io/iostreams/zlibstream.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/sg_inlines.h>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
using std::string;
|
||||
using traits = std::char_traits<char>;
|
||||
using simgear::enumValue;
|
||||
|
||||
// Cast an enum value to its underlying type
|
||||
template <typename T>
|
||||
static constexpr typename std::underlying_type<T>::type enumValue(T e) {
|
||||
return static_cast<typename std::underlying_type<T>::type>(e);
|
||||
}
|
||||
using traits = std::char_traits<char>;
|
||||
|
||||
// Private utility function
|
||||
static string zlibErrorMessage(const z_stream& zstream, int errorCode)
|
||||
|
@ -33,6 +33,7 @@ void testTarGz()
|
||||
|
||||
SG_VERIFY(TarExtractor::isTarData(buf, bufSize));
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
void testPlainTar()
|
||||
@ -48,12 +49,13 @@ void testPlainTar()
|
||||
|
||||
SG_VERIFY(TarExtractor::isTarData(buf, bufSize));
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
int main (int ac, char ** av)
|
||||
int main(int ac, char ** av)
|
||||
{
|
||||
testTarGz();
|
||||
testPlainTar();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -403,22 +403,26 @@ bool TarExtractor::isTarData(const uint8_t* bytes, size_t count)
|
||||
z.avail_in = count;
|
||||
|
||||
if (inflateInit2(&z, ZLIB_INFLATE_WINDOW_BITS | ZLIB_DECODE_GZIP_HEADER) != Z_OK) {
|
||||
inflateEnd(&z);
|
||||
return false;
|
||||
}
|
||||
|
||||
int result = inflate(&z, Z_SYNC_FLUSH);
|
||||
if (result != Z_OK) {
|
||||
SG_LOG(SG_IO, SG_WARN, "inflate failed:" << result);
|
||||
inflateEnd(&z);
|
||||
return false; // not tar data
|
||||
}
|
||||
|
||||
size_t written = 4096 - z.avail_out;
|
||||
if (written < TAR_HEADER_BLOCK_SIZE) {
|
||||
SG_LOG(SG_IO, SG_WARN, "insufficient data for header");
|
||||
inflateEnd(&z);
|
||||
return false;
|
||||
}
|
||||
|
||||
header = reinterpret_cast<UstarHeaderBlock*>(zlibOutput);
|
||||
inflateEnd(&z);
|
||||
} else {
|
||||
// uncompressed tar
|
||||
if (count < TAR_HEADER_BLOCK_SIZE) {
|
||||
|
@ -2,7 +2,11 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
@ -286,6 +290,49 @@ void test_permissions()
|
||||
SG_CHECK_EQUAL(fileInRW.canWrite(), false);
|
||||
}
|
||||
|
||||
void test_comparisons()
|
||||
{
|
||||
std::cout << "Testing comparisons\n";
|
||||
|
||||
SG_CHECK_EQUAL(SGPath("/abc/def ghi"), SGPath("/abc/def ghi"));
|
||||
SG_CHECK_NE(SGPath("/abc"), SGPath("abc"));
|
||||
SG_CHECK_LT(SGPath(""), SGPath("/"));
|
||||
SG_CHECK_LT(SGPath("A"), SGPath("a"));
|
||||
SG_CHECK_LE(SGPath(""), SGPath("/"));
|
||||
SG_CHECK_LE(SGPath("/"), SGPath("/"));
|
||||
SG_CHECK_GT(SGPath("a"), SGPath("A"));
|
||||
SG_CHECK_GE(SGPath("a"), SGPath("A"));
|
||||
SG_CHECK_GE(SGPath("a"), SGPath("a"));
|
||||
|
||||
std::vector<SGPath> origVector({
|
||||
std::string("/zer/gh/tr aze"),
|
||||
std::string("/abc/def/ttt"),
|
||||
std::string("/abc/def/ddd"),
|
||||
std::string("/a"),
|
||||
std::string("")});
|
||||
std::vector<SGPath> sortedVector({
|
||||
std::string(""),
|
||||
std::string("/a"),
|
||||
std::string("/abc/def/ddd"),
|
||||
std::string("/abc/def/ttt"),
|
||||
std::string("/zer/gh/tr aze")});
|
||||
|
||||
std::sort(origVector.begin(), origVector.end());
|
||||
SG_CHECK_EQUAL_NOSTREAM(origVector, sortedVector);
|
||||
}
|
||||
|
||||
void test_hash_function()
|
||||
{
|
||||
std::cout << "Testing the std::hash<SGPath> specialization\n";
|
||||
|
||||
const SGPath nullPath{};
|
||||
const SGPath p{"/abc/def"};
|
||||
|
||||
SG_CHECK_EQUAL(std::hash<SGPath>{}(nullPath), std::hash<SGPath>{}(nullPath));
|
||||
SG_CHECK_EQUAL(std::hash<SGPath>{}(p), std::hash<SGPath>{}(p));
|
||||
SG_CHECK_NE(std::hash<SGPath>{}(p), std::hash<SGPath>{}(p / "foobar"));
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
SGPath pa;
|
||||
@ -389,12 +436,11 @@ int main(int argc, char* argv[])
|
||||
SG_CHECK_EQUAL(pp.canWrite(), false);
|
||||
|
||||
test_dir();
|
||||
|
||||
test_path_dir();
|
||||
|
||||
test_path_dir();
|
||||
test_permissions();
|
||||
|
||||
test_update_dir();
|
||||
test_update_dir();
|
||||
test_comparisons();
|
||||
test_hash_function();
|
||||
|
||||
cout << "all tests passed OK" << endl;
|
||||
return 0; // passed
|
||||
|
@ -240,44 +240,6 @@ SGPath SGPath::fromUtf8(const std::string& bytes, PermissionChecker p)
|
||||
return SGPath(bytes, p);
|
||||
}
|
||||
|
||||
|
||||
SGPath::SGPath(const SGPath& p) :
|
||||
path(p.path),
|
||||
_permission_checker(p._permission_checker),
|
||||
_cached(p._cached),
|
||||
_rwCached(p._rwCached),
|
||||
_cacheEnabled(p._cacheEnabled),
|
||||
_canRead(p._canRead),
|
||||
_canWrite(p._canWrite),
|
||||
_exists(p._exists),
|
||||
_isDir(p._isDir),
|
||||
_isFile(p._isFile),
|
||||
_modTime(p._modTime),
|
||||
_size(p._size)
|
||||
{
|
||||
}
|
||||
|
||||
SGPath& SGPath::operator=(const SGPath& p)
|
||||
{
|
||||
path = p.path;
|
||||
_permission_checker = p._permission_checker,
|
||||
_cached = p._cached;
|
||||
_rwCached = p._rwCached;
|
||||
_cacheEnabled = p._cacheEnabled;
|
||||
_canRead = p._canRead;
|
||||
_canWrite = p._canWrite;
|
||||
_exists = p._exists;
|
||||
_isDir = p._isDir;
|
||||
_isFile = p._isFile;
|
||||
_modTime = p._modTime;
|
||||
_size = p._size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// destructor
|
||||
SGPath::~SGPath() {
|
||||
}
|
||||
|
||||
// set path
|
||||
void SGPath::set( const string& p ) {
|
||||
path = p;
|
||||
@ -780,6 +742,18 @@ bool SGPath::operator!=(const SGPath& other) const
|
||||
return (path != other.path);
|
||||
}
|
||||
|
||||
bool operator<(const SGPath& lhs, const SGPath& rhs)
|
||||
{ return lhs.path < rhs.path; }
|
||||
|
||||
bool operator>(const SGPath& lhs, const SGPath& rhs)
|
||||
{ return operator<(rhs, lhs); }
|
||||
|
||||
bool operator<=(const SGPath& lhs, const SGPath& rhs)
|
||||
{ return !operator>(lhs, rhs); }
|
||||
|
||||
bool operator>=(const SGPath& lhs, const SGPath& rhs)
|
||||
{ return !operator<(lhs, rhs); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool SGPath::rename(const SGPath& newName)
|
||||
{
|
||||
|
@ -28,12 +28,14 @@
|
||||
#ifndef _SG_PATH_HXX
|
||||
#define _SG_PATH_HXX
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -65,11 +67,6 @@ public:
|
||||
/** Default constructor */
|
||||
explicit SGPath(PermissionChecker validator = NULL);
|
||||
|
||||
/** Copy contructor */
|
||||
SGPath(const SGPath& p);
|
||||
|
||||
SGPath& operator=(const SGPath& p);
|
||||
|
||||
/**
|
||||
* Construct a path based on the starting path provided.
|
||||
* @param p initial path
|
||||
@ -87,9 +84,6 @@ public:
|
||||
const std::string& r,
|
||||
PermissionChecker validator = NULL );
|
||||
|
||||
/** Destructor */
|
||||
~SGPath();
|
||||
|
||||
/**
|
||||
* Set path to a new value
|
||||
* @param p new path
|
||||
@ -99,6 +93,8 @@ public:
|
||||
|
||||
bool operator==(const SGPath& other) const;
|
||||
bool operator!=(const SGPath& other) const;
|
||||
// Other comparison operators are declared below
|
||||
friend bool operator<(const SGPath& lhs, const SGPath& rhs);
|
||||
|
||||
void setPermissionChecker(PermissionChecker validator);
|
||||
PermissionChecker getPermissionChecker() const;
|
||||
@ -190,8 +186,8 @@ public:
|
||||
* Get the path string
|
||||
* @return path string
|
||||
*/
|
||||
std::string str() const { return path; }
|
||||
std::string utf8Str() const { return path; }
|
||||
std::string str() const noexcept { return path; }
|
||||
std::string utf8Str() const noexcept { return path; }
|
||||
|
||||
std::string local8BitStr() const;
|
||||
|
||||
@ -357,6 +353,24 @@ private:
|
||||
mutable size_t _size;
|
||||
};
|
||||
|
||||
// Other comparison operators are in the class definition block
|
||||
bool operator> (const SGPath& lhs, const SGPath& rhs);
|
||||
bool operator<=(const SGPath& lhs, const SGPath& rhs);
|
||||
bool operator>=(const SGPath& lhs, const SGPath& rhs);
|
||||
|
||||
// Hash function for SGPath
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<SGPath>
|
||||
{
|
||||
std::size_t operator()(const SGPath& path) const noexcept
|
||||
{
|
||||
return std::hash<std::string>{}(path.utf8Str());
|
||||
}
|
||||
};
|
||||
} // of namespace std
|
||||
|
||||
/// Output to an ostream
|
||||
template<typename char_type, typename traits_type>
|
||||
inline
|
||||
|
@ -17,7 +17,6 @@ set(DETAIL_HEADERS
|
||||
detail/from_nasal_helper.hxx
|
||||
detail/functor_templates.hxx
|
||||
detail/nasal_traits.hxx
|
||||
detail/NasalObject_callMethod_templates.hxx
|
||||
detail/to_nasal_helper.hxx
|
||||
)
|
||||
|
||||
|
@ -23,9 +23,6 @@
|
||||
#include "NasalObjectHolder.hxx"
|
||||
#include "Ghost.hxx"
|
||||
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
/**
|
||||
@ -48,14 +45,21 @@ namespace nasal
|
||||
|
||||
bool valid() const;
|
||||
|
||||
// Build dependency for CMake, gcc, etc.
|
||||
#define SG_DONT_DO_ANYTHING
|
||||
# include <simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx>
|
||||
#undef SG_DONT_DO_ANYTHING
|
||||
template<class Ret, class ... Args>
|
||||
Ret callMethod(const std::string& name, Args ... args)
|
||||
{
|
||||
if( !_nasal_impl.valid() )
|
||||
return Ret();
|
||||
|
||||
#define BOOST_PP_ITERATION_LIMITS (0, 9)
|
||||
#define BOOST_PP_FILENAME_1 <simgear/nasal/cppbind/detail/NasalObject_callMethod_templates.hxx>
|
||||
#include BOOST_PP_ITERATE()
|
||||
Context ctx;
|
||||
auto func = get_member<boost::function<Ret (nasal::Me, Args...)>>(
|
||||
ctx, _nasal_impl.get_naRef(), name
|
||||
);
|
||||
if( func )
|
||||
return func(nasal::to_nasal(ctx, this), args...);
|
||||
|
||||
return Ret();
|
||||
}
|
||||
|
||||
bool _set(naContext c, const std::string& key, naRef val);
|
||||
bool _get(naContext c, const std::string& key, naRef& out);
|
||||
|
@ -1,35 +0,0 @@
|
||||
#ifndef SG_NASAL_OBJECT_HXX_
|
||||
# error Nasal cppbind - do not include this file!
|
||||
#endif
|
||||
|
||||
#ifndef SG_DONT_DO_ANYTHING
|
||||
#define n BOOST_PP_ITERATION()
|
||||
|
||||
#define SG_CALL_ARG(z, n, dummy)\
|
||||
to_nasal<typename boost::call_traits<A##n>::param_type>(ctx, a##n)
|
||||
|
||||
template<
|
||||
class Ret
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)
|
||||
>
|
||||
Ret callMethod( const std::string& name
|
||||
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(n, A, a) )
|
||||
{
|
||||
if( !_nasal_impl.valid() )
|
||||
return Ret();
|
||||
|
||||
typedef boost::function<Ret (nasal::Me BOOST_PP_ENUM_TRAILING_PARAMS(n, A))>
|
||||
MemFunc;
|
||||
|
||||
Context ctx;
|
||||
MemFunc f = get_member<MemFunc>(ctx, _nasal_impl.get_naRef(), name.c_str());
|
||||
if( f )
|
||||
return f(nasal::to_nasal(ctx, this) BOOST_PP_ENUM_TRAILING_PARAMS(n, a));
|
||||
|
||||
return Ret();
|
||||
}
|
||||
|
||||
#undef SG_CALL_ARG
|
||||
|
||||
#undef n
|
||||
#endif // SG_DONT_DO_ANYTHING
|
@ -151,13 +151,14 @@ public:
|
||||
std::string u = dl->realUrl();
|
||||
if (status == Delegate::STATUS_SUCCESS) {
|
||||
thumbnailCache[u].requestPending = false;
|
||||
fireDataForThumbnail(u, reinterpret_cast<const uint8_t*>(bytes.data()), bytes.size());
|
||||
|
||||
// if this was a network load, rather than a re-load from the disk cache,
|
||||
// then persist to disk now.
|
||||
if (strutils::starts_with(request->url(), "http")) {
|
||||
addToPersistentCache(u, bytes);
|
||||
}
|
||||
|
||||
fireDataForThumbnail(u, reinterpret_cast<const uint8_t*>(bytes.data()), bytes.size());
|
||||
} else if (status == Delegate::FAIL_HTTP_FORBIDDEN) {
|
||||
// treat this as rate-limiting failure, at least from some mirrors
|
||||
// (eg Ibiblio) and retry up to the max count
|
||||
@ -220,6 +221,10 @@ public:
|
||||
sg_ofstream fstream(cachePath, std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
fstream.write(imageBytes.data(), imageBytes.size());
|
||||
fstream.close();
|
||||
|
||||
auto it = thumbnailCache.find(url);
|
||||
assert(it != thumbnailCache.end());
|
||||
it->second.pathOnDisk = cachePath;
|
||||
}
|
||||
|
||||
bool checkPersistentCache(const std::string& url)
|
||||
|
@ -74,10 +74,12 @@ osg::Vec2d eventToWindowCoords(const osgGA::GUIEventAdapter& ea)
|
||||
class SGPickAnimation::PickCallback : public SGPickCallback {
|
||||
public:
|
||||
PickCallback(const SGPropertyNode* configNode,
|
||||
SGPropertyNode* modelRoot) :
|
||||
SGPropertyNode* modelRoot,
|
||||
SGSharedPtr<SGCondition const> condition) :
|
||||
SGPickCallback(PriorityPanel),
|
||||
_repeatable(configNode->getBoolValue("repeatable", false)),
|
||||
_repeatInterval(configNode->getDoubleValue("interval-sec", 0.1))
|
||||
_repeatInterval(configNode->getDoubleValue("interval-sec", 0.1)),
|
||||
_condition(condition)
|
||||
{
|
||||
std::vector<SGPropertyNode_ptr> bindings;
|
||||
|
||||
@ -98,63 +100,76 @@ osg::Vec2d eventToWindowCoords(const osgGA::GUIEventAdapter& ea)
|
||||
void addHoverBindings(const SGPropertyNode* hoverNode,
|
||||
SGPropertyNode* modelRoot)
|
||||
{
|
||||
_hover = readBindingList(hoverNode->getChildren("binding"), modelRoot);
|
||||
if (!_condition || _condition->test()) {
|
||||
_hover = readBindingList(hoverNode->getChildren("binding"), modelRoot);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool buttonPressed( int button,
|
||||
const osgGA::GUIEventAdapter&,
|
||||
const Info& )
|
||||
{
|
||||
if (_buttons.find(button) == _buttons.end()) {
|
||||
return false;
|
||||
}
|
||||
if (!_condition || _condition->test()) {
|
||||
if (_buttons.find(button) == _buttons.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!anyBindingEnabled(_bindingsDown)) {
|
||||
return false;
|
||||
}
|
||||
if (!anyBindingEnabled(_bindingsDown)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fireBindingList(_bindingsDown);
|
||||
_repeatTime = -_repeatInterval; // anti-bobble: delay start of repeat
|
||||
return true;
|
||||
fireBindingList(_bindingsDown);
|
||||
_repeatTime = -_repeatInterval; // anti-bobble: delay start of repeat
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual void buttonReleased( int keyModState,
|
||||
const osgGA::GUIEventAdapter&,
|
||||
const Info* )
|
||||
{
|
||||
SG_UNUSED(keyModState);
|
||||
fireBindingList(_bindingsUp);
|
||||
if (!_condition || _condition->test()) {
|
||||
SG_UNUSED(keyModState);
|
||||
fireBindingList(_bindingsUp);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void update(double dt, int keyModState)
|
||||
{
|
||||
SG_UNUSED(keyModState);
|
||||
if (!_repeatable)
|
||||
return;
|
||||
if (!_condition || _condition->test()) {
|
||||
SG_UNUSED(keyModState);
|
||||
if (!_repeatable)
|
||||
return;
|
||||
|
||||
_repeatTime += dt;
|
||||
while (_repeatInterval < _repeatTime) {
|
||||
_repeatTime -= _repeatInterval;
|
||||
fireBindingList(_bindingsDown);
|
||||
}
|
||||
_repeatTime += dt;
|
||||
while (_repeatInterval < _repeatTime) {
|
||||
_repeatTime -= _repeatInterval;
|
||||
fireBindingList(_bindingsDown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool hover( const osg::Vec2d& windowPos,
|
||||
const Info& )
|
||||
{
|
||||
if (!anyBindingEnabled(_hover)) {
|
||||
return false;
|
||||
if (!_condition || _condition->test()) {
|
||||
if (!anyBindingEnabled(_hover)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SGPropertyNode_ptr params(new SGPropertyNode);
|
||||
params->setDoubleValue("x", windowPos.x());
|
||||
params->setDoubleValue("y", windowPos.y());
|
||||
fireBindingList(_hover, params.ptr());
|
||||
return true;
|
||||
}
|
||||
|
||||
SGPropertyNode_ptr params(new SGPropertyNode);
|
||||
params->setDoubleValue("x", windowPos.x());
|
||||
params->setDoubleValue("y", windowPos.y());
|
||||
fireBindingList(_hover, params.ptr());
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string getCursor() const
|
||||
{ return _cursorName; }
|
||||
private:
|
||||
SGSharedPtr<SGCondition const> _condition;
|
||||
SGBindingList _bindingsDown;
|
||||
SGBindingList _bindingsUp;
|
||||
SGBindingList _hover;
|
||||
@ -247,8 +262,9 @@ class SGPickAnimation::VncCallback : public SGPickCallback {
|
||||
public:
|
||||
VncCallback(const SGPropertyNode* configNode,
|
||||
SGPropertyNode* modelRoot,
|
||||
osg::Group *node)
|
||||
: _node(node)
|
||||
osg::Group *node,
|
||||
SGSharedPtr<SGCondition const> condition)
|
||||
: _node(node), _condition(condition)
|
||||
{
|
||||
SG_LOG(SG_INPUT, SG_DEBUG, "Configuring VNC callback");
|
||||
const char *cornernames[3] = {"top-left", "top-right", "bottom-left"};
|
||||
@ -270,29 +286,35 @@ public:
|
||||
const osgGA::GUIEventAdapter&,
|
||||
const Info& info )
|
||||
{
|
||||
SGVec3d loc(info.local);
|
||||
SG_LOG(SG_INPUT, SG_DEBUG, "VNC pressed " << button << ": " << loc);
|
||||
loc -= _topLeft;
|
||||
_x = dot(loc, _toRight) / _squaredRight;
|
||||
_y = dot(loc, _toDown) / _squaredDown;
|
||||
if (_x<0) _x = 0; else if (_x > 1) _x = 1;
|
||||
if (_y<0) _y = 0; else if (_y > 1) _y = 1;
|
||||
VncVisitor vv(_x, _y, 1 << button);
|
||||
_node->accept(vv);
|
||||
return vv.wasSuccessful();
|
||||
|
||||
if (!_condition || _condition->test()) {
|
||||
SGVec3d loc(info.local);
|
||||
SG_LOG(SG_INPUT, SG_DEBUG, "VNC pressed " << button << ": " << loc);
|
||||
loc -= _topLeft;
|
||||
_x = dot(loc, _toRight) / _squaredRight;
|
||||
_y = dot(loc, _toDown) / _squaredDown;
|
||||
if (_x < 0) _x = 0; else if (_x > 1) _x = 1;
|
||||
if (_y < 0) _y = 0; else if (_y > 1) _y = 1;
|
||||
VncVisitor vv(_x, _y, 1 << button);
|
||||
_node->accept(vv);
|
||||
return vv.wasSuccessful();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual void buttonReleased( int keyModState,
|
||||
const osgGA::GUIEventAdapter&,
|
||||
const Info* )
|
||||
{
|
||||
SG_UNUSED(keyModState);
|
||||
SG_LOG(SG_INPUT, SG_DEBUG, "VNC release");
|
||||
VncVisitor vv(_x, _y, 0);
|
||||
_node->accept(vv);
|
||||
if (!_condition || _condition->test()) {
|
||||
SG_UNUSED(keyModState);
|
||||
SG_LOG(SG_INPUT, SG_DEBUG, "VNC release");
|
||||
VncVisitor vv(_x, _y, 0);
|
||||
_node->accept(vv);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SGSharedPtr<SGCondition const> _condition;
|
||||
|
||||
double _x, _y;
|
||||
osg::ref_ptr<osg::Group> _node;
|
||||
SGVec3d _topLeft, _toRight, _toDown;
|
||||
@ -304,6 +326,8 @@ private:
|
||||
SGPickAnimation::SGPickAnimation(simgear::SGTransientModelData &modelData) :
|
||||
SGAnimation(modelData)
|
||||
{
|
||||
_condition = getCondition();
|
||||
|
||||
std::vector<SGPropertyNode_ptr> names = modelData.getConfigNode()->getChildren("proxy-name");
|
||||
for (unsigned i = 0; i < names.size(); ++i) {
|
||||
_proxyNames.push_back(names[i]->getStringValue());
|
||||
@ -451,7 +475,7 @@ SGPickAnimation::setupCallbacks(SGSceneUserData* ud, osg::Group* parent)
|
||||
std::vector<SGPropertyNode_ptr> actions;
|
||||
actions = getConfig()->getChildren("action");
|
||||
for (unsigned int i = 0; i < actions.size(); ++i) {
|
||||
pickCb = new PickCallback(actions[i], getModelRoot());
|
||||
pickCb = new PickCallback(actions[i], getModelRoot(), _condition);
|
||||
ud->addPickCallback(pickCb);
|
||||
}
|
||||
|
||||
@ -459,7 +483,7 @@ SGPickAnimation::setupCallbacks(SGSceneUserData* ud, osg::Group* parent)
|
||||
if (!pickCb) {
|
||||
// make a trivial PickCallback to hang the hovered off of
|
||||
SGPropertyNode_ptr dummyNode(new SGPropertyNode);
|
||||
pickCb = new PickCallback(dummyNode.ptr(), getModelRoot());
|
||||
pickCb = new PickCallback(dummyNode.ptr(), getModelRoot(), _condition);
|
||||
ud->addPickCallback(pickCb);
|
||||
}
|
||||
|
||||
@ -469,7 +493,7 @@ SGPickAnimation::setupCallbacks(SGSceneUserData* ud, osg::Group* parent)
|
||||
// Look for the VNC sessions that want raw mouse input
|
||||
actions = getConfig()->getChildren("vncaction");
|
||||
for (unsigned int i = 0; i < actions.size(); ++i) {
|
||||
ud->addPickCallback(new VncCallback(actions[i], getModelRoot(), parent));
|
||||
ud->addPickCallback(new VncCallback(actions[i], getModelRoot(), parent, _condition));
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,11 +532,13 @@ public:
|
||||
|
||||
|
||||
KnobSliderPickCallback(const SGPropertyNode* configNode,
|
||||
SGPropertyNode* modelRoot) :
|
||||
SGPropertyNode* modelRoot,
|
||||
SGSharedPtr<SGCondition const> condition) :
|
||||
SGPickCallback(PriorityPanel),
|
||||
_direction(DIRECTION_NONE),
|
||||
_repeatInterval(configNode->getDoubleValue("interval-sec", 0.1)),
|
||||
_dragDirection(DRAG_DEFAULT)
|
||||
_dragDirection(DRAG_DEFAULT),
|
||||
_condition(condition)
|
||||
{
|
||||
readOptionalBindingList(configNode, modelRoot, "action", _action);
|
||||
readOptionalBindingList(configNode, modelRoot, "increase", _bindingsIncrease);
|
||||
@ -560,41 +586,49 @@ public:
|
||||
const osgGA::GUIEventAdapter& ea,
|
||||
const Info& )
|
||||
{
|
||||
// the 'be nice to Mac / laptop' users option; alt-clicking spins the
|
||||
if (!_condition || _condition->test()) {
|
||||
// the 'be nice to Mac / laptop' users option; alt-clicking spins the
|
||||
// opposite direction. Should make this configurable
|
||||
if ((button == 0) && (ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_ALT)) {
|
||||
button = 1;
|
||||
if ((button == 0) && (ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_ALT)) {
|
||||
button = 1;
|
||||
}
|
||||
|
||||
int increaseMouseWheel = static_knobMouseWheelAlternateDirection ? 3 : 4;
|
||||
int decreaseMouseWheel = static_knobMouseWheelAlternateDirection ? 4 : 3;
|
||||
|
||||
_direction = DIRECTION_NONE;
|
||||
if ((button == 0) || (button == increaseMouseWheel)) {
|
||||
_direction = DIRECTION_INCREASE;
|
||||
}
|
||||
else if ((button == 1) || (button == decreaseMouseWheel)) {
|
||||
_direction = DIRECTION_DECREASE;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
_lastFirePos = eventToWindowCoords(ea);
|
||||
// delay start of repeat, makes dragging more usable
|
||||
_repeatTime = -_repeatInterval;
|
||||
_hasDragged = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int increaseMouseWheel = static_knobMouseWheelAlternateDirection ? 3 : 4;
|
||||
int decreaseMouseWheel = static_knobMouseWheelAlternateDirection ? 4 : 3;
|
||||
|
||||
_direction = DIRECTION_NONE;
|
||||
if ((button == 0) || (button == increaseMouseWheel)) {
|
||||
_direction = DIRECTION_INCREASE;
|
||||
} else if ((button == 1) || (button == decreaseMouseWheel)) {
|
||||
_direction = DIRECTION_DECREASE;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
_lastFirePos = eventToWindowCoords(ea);
|
||||
// delay start of repeat, makes dragging more usable
|
||||
_repeatTime = -_repeatInterval;
|
||||
_hasDragged = false;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void buttonReleased( int keyModState,
|
||||
const osgGA::GUIEventAdapter&,
|
||||
const Info* )
|
||||
{
|
||||
// for *clicks*, we only fire on button release
|
||||
if (!_hasDragged) {
|
||||
fire(keyModState & osgGA::GUIEventAdapter::MODKEY_SHIFT, _direction);
|
||||
if (!_condition || _condition->test()) {
|
||||
|
||||
// for *clicks*, we only fire on button release
|
||||
if (!_hasDragged) {
|
||||
fire(keyModState & osgGA::GUIEventAdapter::MODKEY_SHIFT, _direction);
|
||||
}
|
||||
|
||||
fireBindingList(_releaseAction);
|
||||
}
|
||||
|
||||
fireBindingList(_releaseAction);
|
||||
}
|
||||
|
||||
DragDirection effectiveDragDirection() const
|
||||
@ -611,32 +645,34 @@ public:
|
||||
virtual void mouseMoved( const osgGA::GUIEventAdapter& ea,
|
||||
const Info* )
|
||||
{
|
||||
_mousePos = eventToWindowCoords(ea);
|
||||
osg::Vec2d deltaMouse = _mousePos - _lastFirePos;
|
||||
|
||||
if (!_hasDragged) {
|
||||
|
||||
double manhattanDist = deltaMouse.x() * deltaMouse.x() + deltaMouse.y() * deltaMouse.y();
|
||||
if (manhattanDist < 5) {
|
||||
// don't do anything, just input noise
|
||||
return;
|
||||
if (!_condition || _condition->test()) {
|
||||
_mousePos = eventToWindowCoords(ea);
|
||||
osg::Vec2d deltaMouse = _mousePos - _lastFirePos;
|
||||
|
||||
if (!_hasDragged) {
|
||||
|
||||
double manhattanDist = deltaMouse.x() * deltaMouse.x() + deltaMouse.y() * deltaMouse.y();
|
||||
if (manhattanDist < 5) {
|
||||
// don't do anything, just input noise
|
||||
return;
|
||||
}
|
||||
|
||||
// user is dragging, disable repeat behaviour
|
||||
_hasDragged = true;
|
||||
}
|
||||
|
||||
double delta = (effectiveDragDirection() == DRAG_VERTICAL) ? deltaMouse.y() : deltaMouse.x();
|
||||
// per-animation scale factor lets the aircraft author tune for expectations,
|
||||
// eg heading setting vs 5-state switch.
|
||||
// then we scale by a global sensitivity, which the user can set.
|
||||
delta *= static_dragSensitivity / _dragScale;
|
||||
|
||||
if (fabs(delta) >= 1.0) {
|
||||
// determine direction from sign of delta
|
||||
Direction dir = (delta > 0.0) ? DIRECTION_INCREASE : DIRECTION_DECREASE;
|
||||
fire(ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_SHIFT, dir);
|
||||
_lastFirePos = _mousePos;
|
||||
}
|
||||
|
||||
// user is dragging, disable repeat behaviour
|
||||
_hasDragged = true;
|
||||
}
|
||||
|
||||
double delta = (effectiveDragDirection() == DRAG_VERTICAL) ? deltaMouse.y() : deltaMouse.x();
|
||||
// per-animation scale factor lets the aircraft author tune for expectations,
|
||||
// eg heading setting vs 5-state switch.
|
||||
// then we scale by a global sensitivity, which the user can set.
|
||||
delta *= static_dragSensitivity / _dragScale;
|
||||
|
||||
if (fabs(delta) >= 1.0) {
|
||||
// determine direction from sign of delta
|
||||
Direction dir = (delta > 0.0) ? DIRECTION_INCREASE : DIRECTION_DECREASE;
|
||||
fire(ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_SHIFT, dir);
|
||||
_lastFirePos = _mousePos;
|
||||
}
|
||||
}
|
||||
|
||||
@ -656,15 +692,19 @@ public:
|
||||
virtual bool hover( const osg::Vec2d& windowPos,
|
||||
const Info& )
|
||||
{
|
||||
if (_hover.empty()) {
|
||||
return false;
|
||||
if (!_condition || _condition->test()) {
|
||||
|
||||
if (_hover.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SGPropertyNode_ptr params(new SGPropertyNode);
|
||||
params->setDoubleValue("x", windowPos.x());
|
||||
params->setDoubleValue("y", windowPos.y());
|
||||
fireBindingList(_hover, params.ptr());
|
||||
return true;
|
||||
}
|
||||
|
||||
SGPropertyNode_ptr params(new SGPropertyNode);
|
||||
params->setDoubleValue("x", windowPos.x());
|
||||
params->setDoubleValue("y", windowPos.y());
|
||||
fireBindingList(_hover, params.ptr());
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void setCursor(const std::string& aName)
|
||||
@ -678,13 +718,15 @@ public:
|
||||
private:
|
||||
void fire(bool isShifted, Direction dir)
|
||||
{
|
||||
const SGBindingList& act(isShifted ? _shiftedAction : _action);
|
||||
const SGBindingList& incr(isShifted ? _shiftedIncrease : _bindingsIncrease);
|
||||
const SGBindingList& decr(isShifted ? _shiftedDecrease : _bindingsDecrease);
|
||||
|
||||
switch (dir) {
|
||||
if (!_condition || _condition->test()) {
|
||||
|
||||
const SGBindingList& act(isShifted ? _shiftedAction : _action);
|
||||
const SGBindingList& incr(isShifted ? _shiftedIncrease : _bindingsIncrease);
|
||||
const SGBindingList& decr(isShifted ? _shiftedDecrease : _bindingsDecrease);
|
||||
|
||||
switch (dir) {
|
||||
case DIRECTION_INCREASE:
|
||||
fireBindingListWithOffset(act, 1, 1);
|
||||
fireBindingListWithOffset(act, 1, 1);
|
||||
fireBindingList(incr);
|
||||
break;
|
||||
case DIRECTION_DECREASE:
|
||||
@ -692,6 +734,7 @@ private:
|
||||
fireBindingList(decr);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -707,6 +750,8 @@ private:
|
||||
double _repeatTime;
|
||||
|
||||
DragDirection _dragDirection;
|
||||
SGSharedPtr<SGCondition const> _condition;
|
||||
|
||||
bool _hasDragged; ///< has the mouse been dragged since the press?
|
||||
osg::Vec2d _mousePos, ///< current window coords location of the mouse
|
||||
_lastFirePos; ///< mouse location where we last fired the bindings
|
||||
@ -719,19 +764,22 @@ private:
|
||||
|
||||
class SGKnobAnimation::UpdateCallback : public osg::NodeCallback {
|
||||
public:
|
||||
UpdateCallback(SGExpressiond const* animationValue) :
|
||||
_animationValue(animationValue)
|
||||
UpdateCallback(SGExpressiond const* animationValue, SGSharedPtr<SGCondition const> condition) :
|
||||
_animationValue(animationValue), _condition(condition)
|
||||
{
|
||||
setName("SGKnobAnimation::UpdateCallback");
|
||||
}
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
SGRotateTransform* transform = static_cast<SGRotateTransform*>(node);
|
||||
transform->setAngleDeg(_animationValue->getValue());
|
||||
traverse(node, nv);
|
||||
if (!_condition || _condition->test()) {
|
||||
SGRotateTransform* transform = static_cast<SGRotateTransform*>(node);
|
||||
transform->setAngleDeg(_animationValue->getValue());
|
||||
traverse(node, nv);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SGSharedPtr<SGCondition const> _condition;
|
||||
SGSharedPtr<SGExpressiond const> _animationValue;
|
||||
};
|
||||
|
||||
@ -739,6 +787,7 @@ private:
|
||||
SGKnobAnimation::SGKnobAnimation(simgear::SGTransientModelData &modelData) :
|
||||
SGPickAnimation(modelData)
|
||||
{
|
||||
_condition = getCondition();
|
||||
SGSharedPtr<SGExpressiond> value = read_value(modelData.getConfigNode(), modelData.getModelRoot(), "-deg",
|
||||
-SGLimitsd::max(), SGLimitsd::max());
|
||||
_animationValue = value->simplify();
|
||||
@ -752,7 +801,7 @@ SGKnobAnimation::createMainGroup(osg::Group* pr)
|
||||
{
|
||||
SGRotateTransform* transform = new SGRotateTransform();
|
||||
|
||||
UpdateCallback* uc = new UpdateCallback(_animationValue);
|
||||
UpdateCallback* uc = new UpdateCallback(_animationValue, _condition);
|
||||
transform->setUpdateCallback(uc);
|
||||
transform->setCenter(_center);
|
||||
transform->setAxis(_axis);
|
||||
@ -764,7 +813,7 @@ SGKnobAnimation::createMainGroup(osg::Group* pr)
|
||||
void
|
||||
SGKnobAnimation::setupCallbacks(SGSceneUserData* ud, osg::Group*)
|
||||
{
|
||||
ud->setPickCallback(new KnobSliderPickCallback(getConfig(), getModelRoot()));
|
||||
ud->setPickCallback(new KnobSliderPickCallback(getConfig(), getModelRoot(), _condition));
|
||||
}
|
||||
|
||||
void SGKnobAnimation::setAlternateMouseWheelDirection(bool aToggle)
|
||||
@ -830,7 +879,7 @@ SGSliderAnimation::createMainGroup(osg::Group* pr)
|
||||
void
|
||||
SGSliderAnimation::setupCallbacks(SGSceneUserData* ud, osg::Group*)
|
||||
{
|
||||
ud->setPickCallback(new KnobSliderPickCallback(getConfig(), getModelRoot()));
|
||||
ud->setPickCallback(new KnobSliderPickCallback(getConfig(), getModelRoot(), _condition));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -45,7 +45,8 @@ protected:
|
||||
|
||||
|
||||
virtual osg::Group* createMainGroup(osg::Group* pr);
|
||||
|
||||
SGSharedPtr<SGCondition const> _condition;
|
||||
|
||||
virtual void setupCallbacks(SGSceneUserData* ud, osg::Group* parent);
|
||||
private:
|
||||
class PickCallback;
|
||||
@ -85,7 +86,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual osg::Group* createMainGroup(osg::Group* pr);
|
||||
|
||||
SGSharedPtr<SGCondition const> _condition;
|
||||
|
||||
virtual void setupCallbacks(SGSceneUserData* ud, osg::Group* parent);
|
||||
|
||||
private:
|
||||
|
@ -202,33 +202,41 @@ void addTreeToLeafGeode(Geode* geode, const SGVec3f& p, const SGVec3f& t)
|
||||
Vec3 pos = toOsg(p);
|
||||
Vec3 ter = toOsg(t);
|
||||
unsigned int numDrawables = geode->getNumDrawables();
|
||||
Geometry* geom
|
||||
= static_cast<Geometry*>(geode->getDrawable(numDrawables - 1));
|
||||
Geometry* geom = static_cast<Geometry*>(geode->getDrawable(numDrawables - 1));
|
||||
Vec3Array* posArray = static_cast<Vec3Array*>(geom->getColorArray());
|
||||
Vec3Array* tnormalArray = NULL;
|
||||
if (use_tree_shadows || use_tree_normals)
|
||||
{tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());}
|
||||
if (posArray->size()
|
||||
>= static_cast<Vec3Array*>(geom->getVertexArray())->size()) {
|
||||
Vec3Array* paramsArray
|
||||
= static_cast<Vec3Array*>(geom->getNormalArray());
|
||||
|
||||
if (use_tree_shadows || use_tree_normals) {
|
||||
tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());
|
||||
}
|
||||
|
||||
if (posArray->size() >= static_cast<Vec3Array*>(geom->getVertexArray())->size()) {
|
||||
Vec3Array* paramsArray = static_cast<Vec3Array*>(geom->getNormalArray());
|
||||
Vec3 params = (*paramsArray)[0];
|
||||
geom = createTreeGeometry(params.x(), params.y(), params.z());
|
||||
posArray = static_cast<Vec3Array*>(geom->getColorArray());
|
||||
if (use_tree_shadows || use_tree_normals)
|
||||
{tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());}
|
||||
|
||||
if (use_tree_shadows || use_tree_normals) {
|
||||
tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());
|
||||
}
|
||||
geode->addDrawable(geom);
|
||||
}
|
||||
posArray->insert(posArray->end(), 4, pos);
|
||||
if (use_tree_shadows || use_tree_normals)
|
||||
{tnormalArray->insert(tnormalArray->end(),4,ter);}
|
||||
size_t numVerts = posArray->size();
|
||||
int imax = 2;
|
||||
if (use_tree_shadows) {imax = 3;}
|
||||
for (int i = 0; i < imax; ++i) {
|
||||
DrawArrays* primSet
|
||||
= static_cast<DrawArrays*>(geom->getPrimitiveSet(i));
|
||||
primSet->setCount(numVerts);
|
||||
|
||||
if (tnormalArray && (use_tree_shadows || use_tree_normals))
|
||||
tnormalArray->insert(tnormalArray->end(), 4, ter);
|
||||
|
||||
if (posArray)
|
||||
{
|
||||
posArray->insert(posArray->end(), 4, pos);
|
||||
|
||||
size_t numVerts = posArray->size();
|
||||
int imax = 2;
|
||||
if (use_tree_shadows) { imax = 3; }
|
||||
for (int i = 0; i < imax; ++i) {
|
||||
DrawArrays* primSet = static_cast<DrawArrays*>(geom->getPrimitiveSet(i));
|
||||
if(primSet != nullptr)
|
||||
primSet->setCount(numVerts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <simgear/misc/test_macros.hxx>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define VERIFY_COLOR(str, r, g, b, a) \
|
||||
SG_VERIFY(simgear::parseColor(str, color)) \
|
||||
@ -28,7 +28,7 @@ int main (int ac, char ** av)
|
||||
SGPropertyNode color_node, color_arg;
|
||||
color_arg.setStringValue("#000000");
|
||||
|
||||
simgear::PropertyInterpolator* interp = new simgear::ColorInterpolator;
|
||||
auto interp = std::unique_ptr<simgear::ColorInterpolator>(new simgear::ColorInterpolator);
|
||||
interp->reset(color_arg);
|
||||
|
||||
interp->update(color_node, 0.5); // with no color it should immediately set to the target
|
||||
|
@ -23,6 +23,7 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#ifndef _SG_INLINES_H
|
||||
@ -123,6 +124,17 @@ void noexceptSwap(T& a, T& b) noexcept
|
||||
swap(a, b);
|
||||
}
|
||||
|
||||
// Cast an enum value to its underlying type (useful with scoped enumerations).
|
||||
//
|
||||
// Example: enum class MyEnum { first = 1, second };
|
||||
// auto e = MyEnum::second;
|
||||
// std::string msg = "MyEnum::second is " +
|
||||
// std::to_string(simgear::enumValue(e));
|
||||
template <typename T>
|
||||
constexpr typename std::underlying_type<T>::type enumValue(T e) {
|
||||
return static_cast<typename std::underlying_type<T>::type>(e);
|
||||
}
|
||||
|
||||
} // of namespace simgear
|
||||
|
||||
#endif // _SG_INLINES_H
|
||||
|
@ -28,10 +28,6 @@ set(HEADERS
|
||||
StateMachine.hxx
|
||||
)
|
||||
|
||||
set(DETAIL_HEADERS
|
||||
detail/function_list_template.hxx
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
SGAtomic.cxx
|
||||
SGBinding.cxx
|
||||
@ -48,7 +44,6 @@ set(SOURCES
|
||||
)
|
||||
|
||||
simgear_component(structure structure "${SOURCES}" "${HEADERS}")
|
||||
simgear_component(structure/detail structure/detail "" "${DETAIL_HEADERS}")
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
#ifndef SG_FUNCTION_LIST_HXX_
|
||||
# error function_list - do not include this file!
|
||||
#endif
|
||||
|
||||
#ifndef SG_DONT_DO_ANYTHING
|
||||
#define n BOOST_PP_ITERATION()
|
||||
#define SG_FUNC_TYPE boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, A))>
|
||||
#define SG_LIST_TYPE std::vector<SG_FUNC_TYPE >
|
||||
|
||||
template<class Ret BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)>
|
||||
class function_list<Ret (BOOST_PP_ENUM_PARAMS(n, A))>:
|
||||
public SG_LIST_TYPE
|
||||
{
|
||||
public:
|
||||
typedef SG_FUNC_TYPE function_type;
|
||||
typedef typename SG_LIST_TYPE::iterator iterator;
|
||||
typedef typename SG_LIST_TYPE::const_iterator const_iterator;
|
||||
|
||||
Ret operator()(BOOST_PP_ENUM_BINARY_PARAMS(n, A, a)) const
|
||||
{
|
||||
if( this->empty() )
|
||||
return Ret();
|
||||
|
||||
const_iterator list_end = --this->end();
|
||||
for(const_iterator f = this->begin(); f != list_end; ++f)
|
||||
if( *f )
|
||||
(*f)(BOOST_PP_ENUM_PARAMS(n, a));
|
||||
|
||||
return (*list_end) ? (*list_end)(BOOST_PP_ENUM_PARAMS(n, a)) : Ret();
|
||||
}
|
||||
};
|
||||
|
||||
#undef n
|
||||
#undef SG_FUNC_TYPE
|
||||
#undef SG_LIST_TYPE
|
||||
|
||||
#endif // SG_DONT_DO_ANYTHING
|
@ -14,6 +14,7 @@
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include <simgear/misc/test_macros.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
@ -81,8 +82,8 @@ void testParse()
|
||||
"</sqr>"
|
||||
"</PropertyList>";
|
||||
|
||||
SGPropertyNode* desc = new SGPropertyNode;
|
||||
readProperties(xml2, strlen(xml2), desc);
|
||||
auto desc = std::unique_ptr<SGPropertyNode>(new SGPropertyNode);
|
||||
readProperties(xml2, strlen(xml2), desc.get());
|
||||
|
||||
SGSharedPtr<SGExpressiond> expr = SGReadDoubleExpression(propertyTree, desc->getChild(0));
|
||||
|
||||
@ -107,4 +108,3 @@ int main(int argc, char* argv[])
|
||||
cout << __FILE__ << ": All tests passed" << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -20,33 +20,43 @@
|
||||
#define SG_FUNCTION_LIST_HXX_
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
template<typename Sig> class function_list;
|
||||
|
||||
// Build dependency for CMake, gcc, etc.
|
||||
# define SG_DONT_DO_ANYTHING
|
||||
# include <simgear/structure/detail/function_list_template.hxx>
|
||||
# undef SG_DONT_DO_ANYTHING
|
||||
|
||||
# define BOOST_PP_ITERATION_LIMITS (0, 3)
|
||||
# define BOOST_PP_FILENAME_1 <simgear/structure/detail/function_list_template.hxx>
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
/**
|
||||
* Handle a list of callbacks like a single boost::function.
|
||||
*
|
||||
* @tparam Sig Function signature.
|
||||
*/
|
||||
template<typename Sig>
|
||||
class function_list<boost::function<Sig> >:
|
||||
public function_list<Sig>
|
||||
template<class Ret, class ... Args>
|
||||
class function_list<Ret(Args...)>:
|
||||
public std::vector<boost::function<Ret(Args...)>>
|
||||
{
|
||||
public:
|
||||
Ret operator()(Args ... args) const
|
||||
{
|
||||
if( this->empty() )
|
||||
return Ret();
|
||||
|
||||
auto list_end = --this->end();
|
||||
for(auto f = this->begin(); f != list_end; ++f)
|
||||
if( *f )
|
||||
(*f)(args...);
|
||||
|
||||
return (*list_end) ? (*list_end)(args...) : Ret();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a list of callbacks with the same signature as the given
|
||||
* boost::function type.
|
||||
*/
|
||||
template<class Ret, class ... Args>
|
||||
class function_list<boost::function<Ret(Args...)>>:
|
||||
public function_list<Ret(Args...)>
|
||||
{
|
||||
|
||||
};
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include "StateMachine.hxx"
|
||||
|
||||
@ -230,11 +231,11 @@ void testParse()
|
||||
</state>
|
||||
</PropertyList>)";
|
||||
|
||||
SGPropertyNode* desc = new SGPropertyNode;
|
||||
readProperties(xml, strlen(xml), desc);
|
||||
auto desc = std::unique_ptr<SGPropertyNode>(new SGPropertyNode);
|
||||
readProperties(xml, strlen(xml), desc.get());
|
||||
|
||||
SGPropertyNode_ptr root(new SGPropertyNode);
|
||||
StateMachine_ptr sm = StateMachine::createFromPlist(desc, root);
|
||||
StateMachine_ptr sm = StateMachine::createFromPlist(desc.get(), root);
|
||||
|
||||
SG_VERIFY(sm->findStateByName("one") != NULL);
|
||||
SG_VERIFY(sm->findStateByName("two") != NULL);
|
||||
@ -250,4 +251,3 @@ int main(int argc, char* argv[])
|
||||
cout << __FILE__ << ": All tests passed" << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user