lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> * Do you use tolua? If not, do you use any other wrapper?

Yes. I tried looking at LuaSWIG briefly but had trouble getting it
compiling and working. I've looked at the other template libraries and
there are some nice ideas in there but I don't like the overhead of
having to bind the code myself.

> * Do you use tolua for C or C++?

Both.

My Doris project uses the LuaGL C bindings and my and GLUIs C++ API.
(http://doris.sf.net/)

> * What features do you miss in tolua?

 - C++ class enums do not live in object tables in tolua. You have to
bodge the enum into the global namespace. eg. class foo { enum { a,b,c
}; }; doesn't work how it should. (I tagged a Doris file on the end so
you can see an example).

 - Option to turn parameter error checking on and off would be nice.
(see code example 1 below).

 - Havent really used Lua 5 or Lua booleans yet but I suppose support
for this would be nice.

> * How could tolua be improved?

 - The size of the binding code generated might be reduced by reusing
some of the strings generated, or using a function to generate the
string.

 - The code base could be commented so its easier to read and modify.

 - You might want to generate documents while generating the binding.
Swig can do this. This isnt really essential, maybe a document generator
will appear in the Lua standard library (Reuben seems to have gone
awfully quiet). You could perhaps add the simple one I put in Doris?
(See formatting in file tagged on).

 - Perhaps you could parse the API to be bound into an intermediate
format so that different bindings could be generated, eg. C or C++. You
might even be able to generate binding to Lua for different languages
through this, eg. Java, C#, Python etc.


That's all I can think of for now. Its pretty good at the moment but can
get a little slow when you're running stuff and its checking all the
params etc. We noticed a moderate speed increase on turning off
parameter checking in the release version once you're happy everything
is running fine.

Nick


-------------------------------
eg.1 : optional error checking. It would be nice to have the default
code added as:
#ifdef GLUT_PARAM_CHECKING ... #endif // GLUT_PARAM_CHECKING but also be
able to override this so you can turn it on and off at runtime:

static int toluaI_glut_glutWireTorus00(lua_State* tolua_S)
{
#ifdef GLUT_PARAM_CHECKING
 if (
     !tolua_istype(tolua_S,1,LUA_TNUMBER,0) ||
     !tolua_istype(tolua_S,2,LUA_TNUMBER,0) ||
     !tolua_istype(tolua_S,3,LUA_TNUMBER,0) ||
     !tolua_istype(tolua_S,4,LUA_TNUMBER,0) ||
     !tolua_isnoobj(tolua_S,5)
 )
  goto tolua_lerror;
 else
#endif // GLUT_PARAM_CHECKING
 {
  GLdouble innerRadius = ((GLdouble)  tolua_getnumber(tolua_S,1,0));
  GLdouble outerRadius = ((GLdouble)  tolua_getnumber(tolua_S,2,0));
  GLint sides = ((GLint)  tolua_getnumber(tolua_S,3,0));
  GLint rings = ((GLint)  tolua_getnumber(tolua_S,4,0));
  {
   glutWireTorus(innerRadius,outerRadius,sides,rings);
  }
 }
 return 0;
#ifdef GLUT_PARAM_CHECKING
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'glutWireTorus'.");
 return 0;
#endif // GLUT_PARAM_CHECKING
}

-----
also ability to turn on and off optionally at runtime would be nice:
-----

static int toluaI_glut_glutWireTorus00(lua_State* tolua_S)
{
if (myGlobalParamSwitch) {
 if (
     !tolua_istype(tolua_S,1,LUA_TNUMBER,0) ||
     !tolua_istype(tolua_S,2,LUA_TNUMBER,0) ||
     !tolua_istype(tolua_S,3,LUA_TNUMBER,0) ||
     !tolua_istype(tolua_S,4,LUA_TNUMBER,0) ||
     !tolua_isnoobj(tolua_S,5)
 )
  goto tolua_lerror;
}
 // else - get rid of this redundant else!
 {
  GLdouble innerRadius = ((GLdouble)  tolua_getnumber(tolua_S,1,0));
  GLdouble outerRadius = ((GLdouble)  tolua_getnumber(tolua_S,2,0));
  GLint sides = ((GLint)  tolua_getnumber(tolua_S,3,0));
  GLint rings = ((GLint)  tolua_getnumber(tolua_S,4,0));
  {
   glutWireTorus(innerRadius,outerRadius,sides,rings);
  }
 }
 return 0;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'glutWireTorus'.");
 return 0;
}

------------------------------------------------------------

/*
    Purpose: Doris toLua packaging.

    Copyright (c) 2001,2002 Nick Trout
    This file is part of Doris. (http://doris.sf.net/)

    Doris is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Doris is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Doris; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
USA

    CVS: $Id: doris.pkg,v 1.15 2002/08/27 12:29:20 trout Exp $
*/

$#include <GL/glut.h>
$#include "algebra3.h"
$#include "doriswin.h"
$#include "dorisobjs.h"
$#include "dorisimage.h"

// Force toLua to create Matrix type for us.
$typedef float MatrixArray;

typedef void* GLUI_Update_CB;
GLUI_Update_CB GLUIUpdateCB;


class Window
{
    Window(char *name);
    int getHandle();
    void setCallback(GLUI_Control *p_ctrl);
};

// Helpers //

//! group="Vector",
//! about=[[A Vector is a 4D vector.
//! This is a wrapper class for the GLUI vec4 vector class.
//! We expose this to Lua so we can use Vectors.]]

class Vector
{
    //! group="Vector", item="new(x,y,z,w)",
    //! about=[[Constructor.]],
    //! params=[[The constructor can accept 0,3 or 4 arguments. 
    //!  If passed no arguments it initialises to (0,0,0,1).]],
    //! eg=[[
    //!  a = Vector:new()
    //!  b = Vector:new(1,2,3)
    //!  a:set(3,2,1)
    //!  b = a+b ]]

    Vector(void);
    Vector(float x,float y,float z,float w);

    //! group="Vector", item="set(x,y,z,w)",
    //! about=[[Set the scalar elements of the vector.]],
    //! params=[[twta
    //!  * x,y,z - the x,y and z elements of the vector.
    //!  * w - optional argument, defaults to 1. ]],
    //! eg=[[
    //!  a = Vector:new()
    //!  a:set(3,2,1) ]]

    void set(float x,float y,float z,float w=1.f);
    
    //! group="Vector", item="+ -",
    //! about=[[Binary vector addition and subtraction operators.]],
    //! eg=[[
    //!  a,b = Vector:new(7,8,9), Vector:new(1,2,3)
    //!  a = a+b
    //!  b = a-b ]]

    //! group="Vector", item="* /",
    //! about=[[Vector scalar scaling operators.]],
    //! eg=[[
    //!  a = Vector:new(7,8,9)
    //!  a = a * .5
    //!  a = a / 2 ]]

    void operator+(Vector& a);
    void operator-(Vector& a);
    void operator*(float s);
    void operator/(float s);
    
    //! group="Vector", item="normalise()",
    //! about=[[Normalise the length of this vector. i.e. make the
length one.]],
    //! eg=[[
    //!  a = Vector:new(7,8,9)
    //!  a:normalise()
    //!  assert( a:length() - 1 < .0001 ) ]]

    //! group="Vector", item="length()",
    //! about=[[Return the length of this Vector.]],
    //! returns=[[The length of the Vector.]],
    //! eg=[[
    //!  a = Vector:new(7,8,9)
    //!  print( a:length() ) ]]

       //! group="Vector", item="dot(vec)",
    //! about=[[Return the dot product of this Vector with the argument
vector passed.]],
    //! params=[[ * vec - The vector to perform the dot product with.
]],
    //! eg=[[
    //!  a,b = Vector:new(1,2,3),Vector:new(2,3,4)
    //!  print( a:dot(b) ) ]]

    void normalise();
    float length();
    void dot(Vector& a);
};

//! group="Matrix",
//! about=[[Matrix is a 4 by 4 matrix.
//! This is a wrapper class for the GLUI mat4 matrix class. 
//! We expose this to Lua so we can use Matrices. 
//! The methods tend not to create new matrices as return values. This
allows the client
//! more control and hopefully should result in the script being faster
through less
//! objects being created. ]]

class Matrix
{
    Matrix(void);
    
       //! group="Matrix", item="dump()",
    //! about=[[Print out the value of the Matrix.]],
    //! eg=[[
    //!  a = Matrix:new()
    //!  a:dump() ]]

       //! group="Matrix", item="set(Matrix m)",
    //! about=[[Set the value of this matrix to the one given. ie.
copy.]],
    //! eg=[[
    //!  a,b = Matrix:new(),Matrix:new()
    //!  a:set(b) ]]

    float& operator [] (int i);
    MatrixArray* getArray();
    void set(Matrix* m);
    void dump();

       //! group="Matrix", item="times(Matrix m), plus(Matrix m),
minus(Matrix m)",
    //! about=[[Matrix multiplication, addition and subtraction.]],
    //! params=" * m - The matrix to apply the operation with.",
    //! eg=[[
    //!  a,b = Matrix:new(), Matrix:new() -- create matrices
    //!  a:makeScale(.5,.5,.5) b:makeTranslate(1,2,3) -- set some values
    //!  a:times(b) b:plus(a) a:minus(b) -- examples of usage ]]

       //! group="Matrix", item="transpose()",
    //! about=[[Transpose the matrix.]],
    //! eg=[[
    //!  a = Matrix:new()
    //!  a:makeTranslate(1,2,3)
    //!  a:transpose() ]]

       //! group="Matrix", item="translateBy(x,y,z)",
    //! about=[[Translate this matrix by the values given.]],
    //! params=[[ * x,y,z - translation required in each axis.]],
    //! eg=[[
    //!  a = Matrix:new()
    //!  a:makeTranslate(1,2,3)
    //!  a:translateBy(-1,-2,-3) -- back to origin ]]

    void times(Matrix& t);
    Vector operator * (Vector& a);
    void plus(Matrix& t);
    void minus(Matrix& t);
    void transpose();
    void translateBy(float x,float y,float z);

    //! group="Matrix", item="makeIndentity()",
    //! about=[[Make this matrix an identity transform. ie. its does
nothing.]],
    //! eg=[[
    //!  a = Matrix:new()
    //!  a:makeIdentity() ]]

       //! group="Matrix", item="makeInverse()",
    //! about=[[Make this matrix the inverse of itself.]],
    //! eg=[[
    //!  a,b = Matrix:new(),Matrix:new()
    //!  a:makeScale(1,2,3)
    //!  b:set(a)
    //!  b:makeInverse() -- b is the inverse of a ]]

       //! group="Matrix", item="makeScale(x,y,z)",
    //! about=[[Create a scaling matrix.]],
    //! params=" * x,y,z - The scale in each axis required.",
    //! eg=[[
    //!  a = Matrix:new()
    //!  a:makeScale(1,2,3) ]]

       //! group="Matrix", item="makeTranslate(x,y,z)",
    //! about=[[Create a translation matrix.]],
    //! params=" * x,y,z - The translation in each axis required.",
    //! eg=[[
    //!  a = Matrix:new()
    //!  a:makeTranslation(1,2,3) ]]

    void makeIdentity();
    void makeInverse();
    void makeScale(float x,float y,float z);
    void makeTranslate(float x,float y,float z);
};

// Work around for enums in classes. toLua struggles with this.
$#define ImageType Image::ImageType

class Image
{
    enum ImageType { 
        ImageUndefined,
        ImageRGB,
        ImageRGBA,
        ImageGrayscale
     };

    Image();
    ~Image();

    bool load(char *filename);
    void unload();

    int getAlphaBits();
    GLLbuffer* getPixels();
    int getHeight();
    int getWidth();
    int getPixelDepth();
    ImageType getImageType();

    void greyscale();
    void convertToNormalMap();
    void scaleDownNormalMap();
    void smooth();
};