zoukankan      html  css  js  c++  java
  • 向lua中添加i64的支持

    lua中默认的number类型是double的,在游戏中很多数据类型用到了64位整型,虽然可以
    通过重定义lua_Number为__int64以支持64位整型,但这又丢失了对浮点数的支持.
    好在可以很方便的往lua中添加自定义的类型,我的需求很简单,可以支持两个i64,或1个
    i64和一个lua_Number的基本算术和关系运算就够了.

    extern int newI64(lua_State *L);
    static const struct luaL_Reg i64Lib[] = {
        {"new",newI64},
        {NULL,NULL},
    };
    
    class Integer64
    {
    public:
        Integer64(__int64 val):m_val(val){}
    
        static void Register2Lua(lua_State *L)
        {
            luaL_getmetatable(L, "kenny.lualib");
            lua_pushstring(L,"int64");
            lua_newtable(L);
    
            
            lua_pushstring(L, "__add");
            lua_pushcfunction(L, i64Add);
            lua_rawset(L, -3);
    
            lua_pushstring(L, "__sub");
            lua_pushcfunction(L, i64Sub);
            lua_rawset(L, -3);
    
            lua_pushstring(L, "__div");
            lua_pushcfunction(L, i64Div);
            lua_rawset(L, -3); 
    
            lua_pushstring(L, "__mul");
            lua_pushcfunction(L, i64Mul);
            lua_rawset(L, -3); 
    
            lua_pushstring(L, "__mod");
            lua_pushcfunction(L, i64Mod);
            lua_rawset(L, -3);
    
            lua_pushstring(L, "__eq");
            lua_pushcfunction(L, i64Eq);
            lua_rawset(L, -3);
    
            lua_pushstring(L, "__lt");
            lua_pushcfunction(L, i64Lt);
            lua_rawset(L, -3);
    
            lua_pushstring(L, "__le");
            lua_pushcfunction(L, i64Le);
            lua_rawset(L, -3);
    
            lua_pushstring(L, "__tostring");
            lua_pushcfunction(L, i64toString);
            lua_rawset(L, -3);
            
            lua_rawset(L,1);
            lua_pop(L,1);
            luaL_register(L,"i64",i64Lib);
            lua_pop(L,1);
            
        }
        
    
        static void setmetatable(lua_State *L)
        {
            luaL_getmetatable(L, "kenny.lualib");
            lua_pushstring(L,"int64");
            lua_gettable(L,-2);
            lua_setmetatable(L, -3);
            lua_pop(L,1);
        }
    
    #ifndef I64_RELA
    #define I64_RELA(OP)\
        Integer64 *i64self  = (Integer64 *)lua_touserdata(L,1);\
        Integer64 *i64other = (Integer64 *)lua_touserdata(L,2);\
        lua_pushboolean(L,i64self->m_val OP i64other->m_val);\
        return 1;
    #endif
    
        static int i64Le(lua_State *L)
        {
            I64_RELA(<=);
        }
    
        static int i64Lt(lua_State *L)
        {
            I64_RELA(<);
        }
    
        static int i64Eq(lua_State *L)
        {
            I64_RELA(==);
        }
    
    #ifndef I64_MATH
    #define I64_MATH(OP)\
        Integer64 *i64self  = (Integer64 *)lua_touserdata(L,1);\
        Integer64 *i64other = (Integer64 *)lua_touserdata(L,2);\
        Integer64 tmp(0);\
        if(!i64other)\
        {\
            tmp.m_val = lua_tonumber(L,2);\
            i64other = &tmp;\
        }\
        if(!i64self)\
        {\
            long num = lua_tonumber(L,1);\
            size_t nbytes = sizeof(Integer64);\
            i64self = (Integer64*)lua_newuserdata(L, nbytes);\
            new(i64self)Integer64(num);\
            i64self->m_val OP= i64other->m_val;\
        }else\
        {\
            i64self->m_val OP= i64other->m_val;\
            lua_pushlightuserdata(L,i64self);\
        }\
        setmetatable(L);\
        return 1;
    #endif
    
        static int i64Mod(lua_State *L)
        {
            I64_MATH(%);
        }
    
        static int i64Div(lua_State *L)
        {
            I64_MATH(/);
        }
    
        static int i64Mul(lua_State *L)
        {
            I64_MATH(*);
        }
    
        static int i64Add(lua_State *L)
        {
            I64_MATH(+);
        }
    
        static int i64Sub(lua_State *L)
        {
            I64_MATH(-);
        }
    
        static int i64toString(lua_State *L)
        {
            Integer64 *i64self  = (Integer64 *)lua_touserdata(L,1);
            luaL_argcheck(L, i64self  != NULL, 1, "userdata expected");    
            char temp[64];
            sprintf(temp, "%I64d", i64self->m_val);
            lua_pushstring(L, temp);
            return 1;
        }
    private:
        __int64 m_val;
    };
    
    
    
    static int newI64(lua_State *L)
    {
        Integer64 *tmp = (Integer64*)lua_touserdata(L,1);
        if(tmp)
            lua_pushlightuserdata(L,tmp);
        else
        {
            long initval = lua_tonumber(L,1);
            size_t nbytes = sizeof(Integer64);
            void *buf = lua_newuserdata(L, nbytes);
            new(buf)Integer64(initval);
        }
        Integer64::setmetatable(L);
        return 1;
    }

    对于算术运算符而言,luaNumber op i64 或 i64 op luaNumber都没问题,

    比较遗憾的是关系运算符不能这样,如果一个luaNumber于一个i64比较则要这样写:

    local a = i64.new(100)

    local b = 100

    print(a == i64.new(b))

  • 相关阅读:
    python 开发中的常用功能
    python 栈&队列&列表的区别
    python 内置函数简介及其作用
    python 正则表达式详解
    python scrapy
    python 文件操作
    python 爬虫实例
    浅谈tcp 与udp
    php正则匹配video 中或者img的宽度和高度。
    android技术积累:开发规范
  • 原文地址:https://www.cnblogs.com/sniperHW/p/2471093.html
Copyright © 2011-2022 走看看