Nasal cppbindings: automatic conversion of vec2 to/from Nasal

This commit is contained in:
Thomas Geymayer 2012-12-17 00:26:02 +01:00
parent a1b7cb5330
commit fd39808ed8
9 changed files with 89 additions and 34 deletions

View File

@ -52,7 +52,7 @@ namespace canvas
_sys.lock()->gcRelease(_gc_key);
}
//------------------------------------------------------------------------------
//----------------------------------------------------------------------------
void EventListener::call(const canvas::EventPtr& event)
{
SystemAdapterPtr sys = _sys.lock();

View File

@ -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<int>(0, (y - first_line_y) / line_height);
size_t line = std::max<int>(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

View File

@ -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<TextOSG> _text;
virtual void childChanged(SGPropertyNode * child);
void handleHit(float x, float y);
};
} // namespace canvas

View File

@ -18,6 +18,10 @@
#ifndef SGVec2_H
#define SGVec2_H
#include "SGLimits.hxx"
#include "SGMathFwd.hxx"
#include "SGMisc.hxx"
#include <iosfwd>
/// 2D Vector Class

View File

@ -5,6 +5,7 @@ set(HEADERS
NasalHash.hxx
from_nasal_detail.hxx
from_nasal.hxx
nasal_traits.hxx
to_nasal.hxx
)

View File

@ -1,3 +1,5 @@
#include <simgear/math/SGVec2.hxx>
#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<float>(c, r) == 4.2f );
std::vector<int> 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<SGVec2f>(c, r) == vec );
std::vector<int> 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<std::string>(0) == "test-arg" );
VERIFY( cc.getArg<std::string>(1) == "" );
naRef args_vec = nasal::to_nasal(c, args);
VERIFY( naIsVector(args_vec) );
// TODO actually do something with the ghosts...
naFreeContext(c);

View File

@ -20,6 +20,8 @@
#ifndef SG_FROM_NASAL_DETAIL_HXX_
#define SG_FROM_NASAL_DETAIL_HXX_
#include "nasal_traits.hxx"
#include <simgear/nasal/nasal.h>
#include <boost/utility/enable_if.hpp>
@ -112,6 +114,20 @@ namespace nasal
return vec;
}
/**
* Convert a Nasal vector of 2 elements to a 2d vector
*/
template<class Vec2>
typename boost::enable_if<is_vec2<Vec2>, Vec2>::type
from_nasal_helper(naContext c, naRef ref, Vec2*)
{
std::vector<double> vec =
from_nasal_helper(c, ref, static_cast<std::vector<double>*>(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_ */

View File

@ -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)
{

View File

@ -20,6 +20,8 @@
#ifndef SG_TO_NASAL_HXX_
#define SG_TO_NASAL_HXX_
#include "nasal_traits.hxx"
#include <simgear/nasal/nasal.h>
#include <boost/utility/enable_if.hpp>
@ -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<class T, size_t N>
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<class Vec2>
typename boost::enable_if<is_vec2<Vec2>, 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_ */