⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tolua_map.c

📁 cegui界面库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* tolua: functions to map features
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Apr 2003
** $Id: tolua_map.c 1141 2006-05-18 23:58:45Z lindquist $
*/

/* This code is free software; you can redistribute it and/or modify it.
** The software provided hereunder is on an "as is" basis, and
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications.
*/

#include "tolua++.h"
#include "tolua_event.h"
#include "lauxlib.h"

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


/* Create metatable
	* Create and register new metatable
*/
static int tolua_newmetatable (lua_State* L, char* name)
{
	int r = luaL_newmetatable(L,name);

	#ifdef LUA_VERSION_NUM /* only lua 5.1 */
	if (r) {
		lua_pushvalue(L, -1);
		lua_pushstring(L, name);
		lua_settable(L, LUA_REGISTRYINDEX); /* reg[mt] = type_name */
	};
	#endif

	if (r)
		tolua_classevents(L); /* set meta events */
	lua_pop(L,1);
	return r;
}

/* Map super classes
	* It sets 'name' as being also a 'base', mapping all super classes of 'base' in 'name'
*/
static void mapsuper (lua_State* L, const char* name, const char* base)
{
	/* push registry.super */
 lua_pushstring(L,"tolua_super");
 lua_rawget(L,LUA_REGISTRYINDEX);    /* stack: super */
	luaL_getmetatable(L,name);          /* stack: super mt */
 lua_rawget(L,-2);                   /* stack: super table */
	if (lua_isnil(L,-1))
	{
	 /* create table */
		lua_pop(L,1);
	 lua_newtable(L);                    /* stack: super table */
	 luaL_getmetatable(L,name);          /* stack: super table mt */
		lua_pushvalue(L,-2);                /* stack: super table mt table */
		lua_rawset(L,-4);                   /* stack: super table */
	}

	/* set base as super class */
	lua_pushstring(L,base);
	lua_pushboolean(L,1);
	lua_rawset(L,-3);                    /* stack: super table */

	/* set all super class of base as super class of name */
	luaL_getmetatable(L,base);          /* stack: super table base_mt */
	lua_rawget(L,-3);                   /* stack: super table base_table */
	if (lua_istable(L,-1))
	{
		/* traverse base table */
		lua_pushnil(L);  /* first key */
		while (lua_next(L,-2) != 0)
		{
			/* stack: ... base_table key value */
			lua_pushvalue(L,-2);    /* stack: ... base_table key value key */
			lua_insert(L,-2);       /* stack: ... base_table key key value */
			lua_rawset(L,-5);       /* stack: ... base_table key */
		}
	}
	lua_pop(L,3);                       /* stack: <empty> */
}

/* creates a 'tolua_ubox' table for base clases, and
// expects the metatable and base metatable on the stack */
static void set_ubox(lua_State* L) {

	/* mt basemt */
	if (!lua_isnil(L, -1)) {
		lua_pushstring(L, "tolua_ubox");
		lua_rawget(L,-2);
	} else {
		lua_pushnil(L);
	};
	/* mt basemt base_ubox */
	if (!lua_isnil(L,-1)) {
		lua_pushstring(L, "tolua_ubox");
		lua_insert(L, -2);
		/* mt basemt key ubox */
		lua_rawset(L,-4);
		/* (mt with ubox) basemt */
	} else {
		/* mt basemt nil */
		lua_pop(L, 1);
		lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
		/* make weak value metatable for ubox table to allow userdata to be
		garbage-collected */
		lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3);               /* stack: string ubox mt */
		lua_setmetatable(L, -2);  /* stack:mt basemt string ubox */
		lua_rawset(L,-4);
	};

};

/* Map inheritance
	* It sets 'name' as derived from 'base' by setting 'base' as metatable of 'name'
*/
static void mapinheritance (lua_State* L, const char* name, const char* base)
{
	/* set metatable inheritance */
	luaL_getmetatable(L,name);

	if (base && *base)
		luaL_getmetatable(L,base);
	else {

		if (lua_getmetatable(L, -1)) { /* already has a mt, we don't overwrite it */
			lua_pop(L, 2);
			return;
		};
		luaL_getmetatable(L,"tolua_commonclass");
	};

	set_ubox(L);

	lua_setmetatable(L,-2);
	lua_pop(L,1);
}

/* Object type
*/
static int tolua_bnd_type (lua_State* L)
{
	tolua_typename(L,lua_gettop(L));
	return 1;
}

/* Take ownership
*/
static int tolua_bnd_takeownership (lua_State* L)
{
	int success = 0;
	if (lua_isuserdata(L,1))
	{
		if (lua_getmetatable(L,1))        /* if metatable? */
		{
			lua_pop(L,1);             /* clear metatable off stack */
			/* force garbage collection to avoid C to reuse a to-be-collected address */
			#ifdef LUA_VERSION_NUM
			lua_gc(L, LUA_GCCOLLECT, 0);
			#else
			lua_setgcthreshold(L,0);
			#endif

			success = tolua_register_gc(L,1);
		}
	}
	lua_pushboolean(L,success!=0);
	return 1;
}

/* Release ownership
*/
static int tolua_bnd_releaseownership (lua_State* L)
{
	int done = 0;
	if (lua_isuserdata(L,1))
	{
		void* u = *((void**)lua_touserdata(L,1));
		/* force garbage collection to avoid releasing a to-be-collected address */
		#ifdef LUA_VERSION_NUM
		lua_gc(L, LUA_GCCOLLECT, 0);
		#else
		lua_setgcthreshold(L,0);
		#endif
		lua_pushstring(L,"tolua_gc");
		lua_rawget(L,LUA_REGISTRYINDEX);
		lua_pushlightuserdata(L,u);
		lua_rawget(L,-2);
		lua_getmetatable(L,1);
		if (lua_rawequal(L,-1,-2))  /* check that we are releasing the correct type */
		{
			lua_pushlightuserdata(L,u);
			lua_pushnil(L);
			lua_rawset(L,-5);
			done = 1;
		}
	}
	lua_pushboolean(L,done!=0);
	return 1;
}

/* Type casting
*/
static int tolua_bnd_cast (lua_State* L)
{

/* // old code
        void* v = tolua_tousertype(L,1,NULL);
        const char* s = tolua_tostring(L,2,NULL);
        if (v && s)
         tolua_pushusertype(L,v,s);
        else
         lua_pushnil(L);
        return 1;
*/

	void* v;
	const char* s;
	if (lua_islightuserdata(L, 1)) {
		v = tolua_touserdata(L, 1, NULL);
	} else {
		v = tolua_tousertype(L, 1, 0);
	};

	s = tolua_tostring(L,2,NULL);
	if (v && s)
	 tolua_pushusertype(L,v,s);
	else
	 lua_pushnil(L);
	return 1;
}

/* Inheritance
*/
static int tolua_bnd_inherit (lua_State* L) {

	/* stack: lua object, c object */
	lua_pushstring(L, ".c_instance");
	lua_pushvalue(L, -2);
	lua_rawset(L, -4);
	/* l_obj[".c_instance"] = c_obj */

	return 0;
};

#ifdef LUA_VERSION_NUM /* lua 5.1 */
static int tolua_bnd_setpeer(lua_State* L) {

	/* stack: userdata, table */
	if (!lua_isuserdata(L, -2)) {
		lua_pushstring(L, "Invalid argument #1 to setpeer: userdata expected.");
		lua_error(L);
	};
	
	if (lua_isnil(L, -1)) {

		lua_pop(L, 1);
		lua_pushvalue(L, TOLUA_NOPEER);
	};
	lua_setfenv(L, -2);

	return 0;
};

static int tolua_bnd_getpeer(lua_State* L) {

	/* stack: userdata */
	lua_getfenv(L, -1);
	if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
		lua_pop(L, 1);
		lua_pushnil(L);
	};
	return 1;
};
#endif

/* static int class_gc_event (lua_State* L); */

TOLUA_API void tolua_open (lua_State* L)
{
 int top = lua_gettop(L);
 lua_pushstring(L,"tolua_opened");
 lua_rawget(L,LUA_REGISTRYINDEX);
 if (!lua_isboolean(L,-1))
 {
  lua_pushstring(L,"tolua_opened"); lua_pushboolean(L,1); lua_rawset(L,LUA_REGISTRYINDEX);

  #ifndef LUA_VERSION_NUM /* only prior to lua 5.1 */
  /* create peer object table */
  lua_pushstring(L, "tolua_peers"); lua_newtable(L);
  /* make weak key metatable for peers indexed by userdata object */
  lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "k"); lua_rawset(L, -3);                /* stack: string peers mt */
  lua_setmetatable(L, -2);   /* stack: string peers */
  lua_rawset(L,LUA_REGISTRYINDEX);
  #endif

  /* create object ptr -> udata mapping table */
  lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
  /* make weak value metatable for ubox table to allow userdata to be
     garbage-collected */
  lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3);               /* stack: string ubox mt */
  lua_setmetatable(L, -2);  /* stack: string ubox */
  lua_rawset(L,LUA_REGISTRYINDEX);

  lua_pushstring(L,"tolua_super"); lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
  lua_pushstring(L,"tolua_gc"); lua_newtable(L);lua_rawset(L,LUA_REGISTRYINDEX);

  /* create gc_event closure */
  lua_pushstring(L, "tolua_gc_event");
  lua_pushstring(L, "tolua_gc");
  lua_rawget(L, LUA_REGISTRYINDEX);
  lua_pushstring(L, "tolua_super");
  lua_rawget(L, LUA_REGISTRYINDEX);
  lua_pushcclosure(L, class_gc_event, 2);
  lua_rawset(L, LUA_REGISTRYINDEX);

  tolua_newmetatable(L,"tolua_commonclass");

  tolua_module(L,NULL,0);
  tolua_beginmodule(L,NULL);
  tolua_module(L,"tolua",0);
  tolua_beginmodule(L,"tolua");
  tolua_function(L,"type",tolua_bnd_type);
  tolua_function(L,"takeownership",tolua_bnd_takeownership);
  tolua_function(L,"releaseownership",tolua_bnd_releaseownership);
  tolua_function(L,"cast",tolua_bnd_cast);
  tolua_function(L,"inherit", tolua_bnd_inherit);
  #ifdef LUA_VERSION_NUM /* lua 5.1 */
  tolua_function(L, "setpeer", tolua_bnd_setpeer);
  tolua_function(L, "getpeer", tolua_bnd_getpeer);
  #endif

  tolua_endmodule(L);
  tolua_endmodule(L);
 }
 lua_settop(L,top);
}

/* Copy a C object
*/
TOLUA_API void* tolua_copy (lua_State* L, void* value, unsigned int size)
{
	void* clone = (void*)malloc(size);
	if (clone)
	 memcpy(clone,value,size);
	else
		tolua_error(L,"insuficient memory",NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -