Just Chai..ming in


#1

I think chaiscript is fantastic. I am integrating it with my own 2d scene graph library and it’s smooth sailing so far

Though holy fuck was it ever an experience learning how to static_cast a function signature for a templated overloaded stand-alone operator +, there wasn’t a lot of direct details in terms of how to do that in the docs and I had to scour the internet for answers.

I’m posting this for reference, it works, I don’t have any questions about it, but I figured it might help someone:

template <class T = float>
class Point{
//STUBBED OUT STUFF HERE
public:
static chaiscript::ChaiScript& hook(chaiscript::ChaiScript &a_script, const std::string &a_postfix) {
	a_script.add(chaiscript::user_type<Point<T>>(), "Point" + a_postfix);
	a_script.add(chaiscript::constructor<Point<T>()>(), "Point" + a_postfix);
	a_script.add(chaiscript::constructor<Point<T>(T, T, T)>(), "Point" + a_postfix);
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(T, T, T)>(&Point<T>::set)), "set");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(T, T)>(&Point<T>::set)), "set");
	a_script.add(chaiscript::fun(&Point<T>::scale), "scale");
	a_script.add(chaiscript::fun(&Point<T>::atOrigin), "atOrigin");
	a_script.add(chaiscript::fun(&Point<T>::normalized), "normalized");
	a_script.add(chaiscript::fun(&Point<T>::magnitude), "magnitude");
	a_script.add(chaiscript::fun(&Point<T>::clear), "clear");
	a_script.add(chaiscript::fun(static_cast<PointPrecision (*)(const Point<T> &, const Point<T> &, AngleType)>(&MV::angle<T>)), "angle");
	a_script.add(chaiscript::fun(static_cast<PointPrecision (*)(const Point<T> &, const Point<T> &)>(&MV::distance<T>)), "distance");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(T, T, T)>(&Point<T>::locate)), "locate");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(T, T)>(&Point<T>::locate)), "locate");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(T, T, T)>(&Point<T>::translate)), "translate");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(T, T)>(&Point<T>::translate)), "translate");
	a_script.add(chaiscript::fun(&Point<T>::x), "x");
	a_script.add(chaiscript::fun(&Point<T>::y), "y");
	a_script.add(chaiscript::fun(&Point<T>::z), "z");

	a_script.add(chaiscript::fun(&Point<T>::operator+=), "+=");
	a_script.add(chaiscript::fun(&Point<T>::operator-=), "-=");

	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(const Point<T> &)>(&Point<T>::operator*=)), "*=");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(const T&)>(&Point<T>::operator*=)), "*=");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(const Scale&)>(&Point<T>::operator*=)), "*=");

	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(const Point<T> &)>(&Point<T>::operator/=)), "/=");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(const T&)>(&Point<T>::operator/=)), "/=");
	a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(const Scale&)>(&Point<T>::operator/=)), "/=");

	a_script.add(chaiscript::fun(static_cast<bool(Point<T>::*)(const Point<T> &) const>(&Point<T>::operator==)), "==");
	a_script.add(chaiscript::fun(static_cast<bool(Point<T>::*)(const T&) const>(&Point<T>::operator==)), "==");

	a_script.add(chaiscript::fun(static_cast<bool(Point<T>::*)(const Point<T> &) const>(&Point<T>::operator!=)), "!=");
	a_script.add(chaiscript::fun(static_cast<bool(Point<T>::*)(const T&) const>(&Point<T>::operator!=)), "!=");

	a_script.add(chaiscript::fun(static_cast<bool(Point<T>::*)(const Point<T> &) const>(&Point<T>::operator<)), "<");
	a_script.add(chaiscript::fun(static_cast<bool(Point<T>::*)(const Point<T> &) const>(&Point<T>::operator>)), ">");

	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const Point<T> &, const Point<T> &)>(MV::operator+<T>)), "+");
	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const Point<T> &, const T &)>(MV::operator+<T>)), "+");
	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const T &, const Point<T> &)>(MV::operator+<T>)), "+");

	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const Point<T> &, const Point<T> &)>(MV::operator-<T>)), "-");
	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const Point<T> &, const T &)>(MV::operator-<T>)), "-");
	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const T &, const Point<T> &)>(MV::operator-<T>)), "-");

	a_script.add(chaiscript::fun(static_cast<Point<T> (*)(const Point<T> &, const Point<T> &)>(MV::operator*<T>)), "*");
	a_script.add(chaiscript::fun(static_cast<Point<T> (*)(const Point<T> &, const T &)>(MV::operator*<T>)), "*");
	a_script.add(chaiscript::fun(static_cast<Point<T> (*)(const Point<T> &, const Scale &)>(MV::operator*<T>)), "*");

	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const Point<T> &, const Point<T> &)>(MV::operator/<T>)), "/");
	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const Point<T> &, const T &)>(MV::operator/<T>)), "/");
	a_script.add(chaiscript::fun(static_cast<Point<T>(*)(const Point<T> &, const Scale &)>(MV::operator/<T>)), "/");

	return a_script;
}
//END OF CLASS
}

#2

This is a somewhat unfortunate side effect of the static typing system of C++.

I have been personally opting for things like this

So you have:

a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(T, T, T)>(&Point<T>::translate)), "translate");
a_script.add(chaiscript::fun(static_cast<Point<T>&(Point<T>::*)(T, T)>(&Point<T>::translate)), "translate");

And I might do this instead, depending on the circumstance:

a_script.add(chaiscript::fun([](Point<T>&t, T,T,T) { return t.translate(T,T,T); }, "translate");
a_script.add(chaiscript::fun([](Point<T>&t, T,T) { return t.translate(T,T); }, "translate");

C++ compilers are VERY good at essentially eliminating the lambda altogether, and I’ve done my best in ChaiScript to make sure there is as little overhead as possible when calling the lambda.

Hopefully that will help some.

-Jason