From fd39808ed8e0926f4389e2d8ad700a48354646a1 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Mon, 17 Dec 2012 00:26:02 +0100 Subject: [PATCH] Nasal cppbindings: automatic conversion of vec2 to/from Nasal --- simgear/canvas/CanvasEventListener.cxx | 2 +- simgear/canvas/elements/CanvasText.cxx | 40 +++++++-------------- simgear/canvas/elements/CanvasText.hxx | 6 ++-- simgear/math/SGVec2.hxx | 4 +++ simgear/nasal/cppbind/CMakeLists.txt | 1 + simgear/nasal/cppbind/cppbind_test.cxx | 14 +++++++- simgear/nasal/cppbind/from_nasal_detail.hxx | 16 +++++++++ simgear/nasal/cppbind/to_nasal.cxx | 6 ++++ simgear/nasal/cppbind/to_nasal.hxx | 34 ++++++++++++++++++ 9 files changed, 89 insertions(+), 34 deletions(-) diff --git a/simgear/canvas/CanvasEventListener.cxx b/simgear/canvas/CanvasEventListener.cxx index 70f458fb..78feb64d 100644 --- a/simgear/canvas/CanvasEventListener.cxx +++ b/simgear/canvas/CanvasEventListener.cxx @@ -52,7 +52,7 @@ namespace canvas _sys.lock()->gcRelease(_gc_key); } - //------------------------------------------------------------------------------ + //---------------------------------------------------------------------------- void EventListener::call(const canvas::EventPtr& event) { SystemAdapterPtr sys = _sys.lock(); diff --git a/simgear/canvas/elements/CanvasText.cxx b/simgear/canvas/elements/CanvasText.cxx index 3e5d7853..c92a9ecf 100644 --- a/simgear/canvas/elements/CanvasText.cxx +++ b/simgear/canvas/elements/CanvasText.cxx @@ -37,7 +37,7 @@ namespace canvas void setFill(const std::string& fill); void setBackgroundColor(const std::string& fill); - osg::Vec2 handleHit(float x, float y); + osg::Vec2 handleHit(const osg::Vec2f& pos); virtual osg::BoundingBox computeBound() const; @@ -79,13 +79,13 @@ namespace canvas } //---------------------------------------------------------------------------- - osg::Vec2 Text::TextOSG::handleHit(float x, float y) + osg::Vec2 Text::TextOSG::handleHit(const osg::Vec2f& pos) { float line_height = _characterHeight + _lineSpacing; // TODO check with align other than TOP float first_line_y = -0.5 * _lineSpacing;//_offset.y() - _characterHeight; - size_t line = std::max(0, (y - first_line_y) / line_height); + size_t line = std::max(0, (pos.y() - first_line_y) / line_height); if( _textureGlyphQuadMap.empty() ) return osg::Vec2(-1, -1); @@ -102,7 +102,7 @@ namespace canvas const float character_width = getCharacterHeight() * getCharacterAspectRatio(); - y = (line + 0.5) * line_height; + float y = (line + 0.5) * line_height; bool line_found = false; for(size_t i = 0; i < line_numbers.size(); ++i) @@ -132,20 +132,21 @@ namespace canvas + HIT_FRACTION * glyphs[i]->getHorizontalAdvance() * character_width; - if( x <= threshold ) + if( pos.x() <= threshold ) { + osg::Vec2 hit(0, y); if( i == 0 || line_numbers[i - 1] != line ) // first character of line - x = coords[i * 4].x(); + hit.x() = coords[i * 4].x(); else if( coords[(i - 1) * 4].x() == coords[(i - 1) * 4 + 2].x() ) // If previous character width is zero set to begin of next character // (Happens eg. with spaces) - x = coords[i * 4].x(); + hit.x() = coords[i * 4].x(); else // position at center between characters - x = 0.5 * (coords[(i - 1) * 4 + 2].x() + coords[i * 4].x()); + hit.x() = 0.5 * (coords[(i - 1) * 4 + 2].x() + coords[i * 4].x()); - return osg::Vec2(x, y); + return hit; } } @@ -266,26 +267,9 @@ namespace canvas #endif //---------------------------------------------------------------------------- - void Text::childChanged(SGPropertyNode* child) + osg::Vec2 Text::getNearestCursor(const osg::Vec2& pos) const { - if( child->getParent() != _node ) - return; - - const std::string& name = child->getNameString(); - if( name == "hit-y" ) - handleHit - ( - _node->getFloatValue("hit-x"), - _node->getFloatValue("hit-y") - ); - } - - //---------------------------------------------------------------------------- - void Text::handleHit(float x, float y) - { - const osg::Vec2& pos = _text->handleHit(x, y); - _node->setFloatValue("cursor-x", pos.x()); - _node->setFloatValue("cursor-y", pos.y()); + return _text->handleHit(pos); } } // namespace canvas diff --git a/simgear/canvas/elements/CanvasText.hxx b/simgear/canvas/elements/CanvasText.hxx index 1c82fe39..7e90c453 100644 --- a/simgear/canvas/elements/CanvasText.hxx +++ b/simgear/canvas/elements/CanvasText.hxx @@ -43,15 +43,13 @@ namespace canvas void setFont(const char* name); void setAlignment(const char* align); + osg::Vec2 getNearestCursor(const osg::Vec2& pos) const; + protected: class TextOSG; osg::ref_ptr _text; - virtual void childChanged(SGPropertyNode * child); - - void handleHit(float x, float y); - }; } // namespace canvas diff --git a/simgear/math/SGVec2.hxx b/simgear/math/SGVec2.hxx index 0695cded..7b9ec15e 100644 --- a/simgear/math/SGVec2.hxx +++ b/simgear/math/SGVec2.hxx @@ -18,6 +18,10 @@ #ifndef SGVec2_H #define SGVec2_H +#include "SGLimits.hxx" +#include "SGMathFwd.hxx" +#include "SGMisc.hxx" + #include /// 2D Vector Class diff --git a/simgear/nasal/cppbind/CMakeLists.txt b/simgear/nasal/cppbind/CMakeLists.txt index 29be4492..636116eb 100644 --- a/simgear/nasal/cppbind/CMakeLists.txt +++ b/simgear/nasal/cppbind/CMakeLists.txt @@ -5,6 +5,7 @@ set(HEADERS NasalHash.hxx from_nasal_detail.hxx from_nasal.hxx + nasal_traits.hxx to_nasal.hxx ) diff --git a/simgear/nasal/cppbind/cppbind_test.cxx b/simgear/nasal/cppbind/cppbind_test.cxx index d8b29b1b..194ebfb3 100644 --- a/simgear/nasal/cppbind/cppbind_test.cxx +++ b/simgear/nasal/cppbind/cppbind_test.cxx @@ -1,3 +1,5 @@ +#include + #include "Ghost.hxx" #include "NasalHash.hxx" @@ -73,8 +75,15 @@ int main(int argc, char* argv[]) VERIFY( naNumValue(r).num == 4.2f ); VERIFY( from_nasal(c, r) == 4.2f ); - std::vector vec; + float test_data[3] = {0, 4, 2}; + r = to_nasal(c, test_data); + + SGVec2f vec(0,2); r = to_nasal(c, vec); + VERIFY( from_nasal(c, r) == vec ); + + std::vector std_vec; + r = to_nasal(c, std_vec); r = to_nasal(c, "string"); try @@ -177,6 +186,9 @@ int main(int argc, char* argv[]) VERIFY( cc.getArg(0) == "test-arg" ); VERIFY( cc.getArg(1) == "" ); + naRef args_vec = nasal::to_nasal(c, args); + VERIFY( naIsVector(args_vec) ); + // TODO actually do something with the ghosts... naFreeContext(c); diff --git a/simgear/nasal/cppbind/from_nasal_detail.hxx b/simgear/nasal/cppbind/from_nasal_detail.hxx index 20a7407f..21d354ae 100644 --- a/simgear/nasal/cppbind/from_nasal_detail.hxx +++ b/simgear/nasal/cppbind/from_nasal_detail.hxx @@ -20,6 +20,8 @@ #ifndef SG_FROM_NASAL_DETAIL_HXX_ #define SG_FROM_NASAL_DETAIL_HXX_ +#include "nasal_traits.hxx" + #include #include @@ -112,6 +114,20 @@ namespace nasal return vec; } + /** + * Convert a Nasal vector of 2 elements to a 2d vector + */ + template + typename boost::enable_if, Vec2>::type + from_nasal_helper(naContext c, naRef ref, Vec2*) + { + std::vector vec = + from_nasal_helper(c, ref, static_cast*>(0)); + if( vec.size() != 2 ) + throw bad_nasal_cast("Expected vector with two elements"); + return Vec2(vec[0], vec[1]); + } + } // namespace nasal #endif /* SG_FROM_NASAL_DETAIL_HXX_ */ diff --git a/simgear/nasal/cppbind/to_nasal.cxx b/simgear/nasal/cppbind/to_nasal.cxx index c4a8e340..ef5b1a21 100644 --- a/simgear/nasal/cppbind/to_nasal.cxx +++ b/simgear/nasal/cppbind/to_nasal.cxx @@ -29,6 +29,12 @@ namespace nasal return ret; } + //---------------------------------------------------------------------------- + naRef to_nasal(naContext c, const char* str) + { + return to_nasal(c, std::string(str)); + } + //---------------------------------------------------------------------------- naRef to_nasal(naContext c, naCFunction func) { diff --git a/simgear/nasal/cppbind/to_nasal.hxx b/simgear/nasal/cppbind/to_nasal.hxx index d90c6ab4..45a27411 100644 --- a/simgear/nasal/cppbind/to_nasal.hxx +++ b/simgear/nasal/cppbind/to_nasal.hxx @@ -20,6 +20,8 @@ #ifndef SG_TO_NASAL_HXX_ #define SG_TO_NASAL_HXX_ +#include "nasal_traits.hxx" + #include #include @@ -37,6 +39,12 @@ namespace nasal */ naRef to_nasal(naContext c, const std::string& str); + /** + * Convert C-string to Nasal string + */ + // We need this to prevent the array overload of to_nasal being called + naRef to_nasal(naContext c, const char* str); + /** * Convert function pointer to Nasal function */ @@ -62,6 +70,19 @@ namespace nasal return naNum(num); } + /** + * Convert a fixed size array to a Nasal vector + */ + template + naRef to_nasal(naContext c, const T(&array)[N]) + { + naRef ret = naNewVector(c); + naVec_setsize(c, ret, N); + for(size_t i = 0; i < N; ++i) + naVec_set(ret, i, to_nasal(c, array[i])); + return ret; + } + /** * Convert std::vector to Nasal vector */ @@ -83,6 +104,19 @@ namespace nasal return ret; } + /** + * Convert a 2d vector to Nasal vector with 2 elements + */ + template + typename boost::enable_if, naRef>::type + to_nasal(naContext c, const Vec2& vec) + { + // We take just double because in Nasal every number is represented as + // double + double nasal_vec[2] = {vec[0], vec[1]}; + return to_nasal(c, nasal_vec); + } + } // namespace nasal #endif /* SG_TO_NASAL_HXX_ */ -- 2.39.5