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

📄 tolua_event.c

📁 tolua++是一个对lua进行封装调用的工具
💻 C
字号:
/* tolua: event functions** Support code for Lua bindings.** Written by Waldemar Celes** TeCGraf/PUC-Rio** Apr 2003** $Id: $*//* 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 <stdio.h>#include "tolua++.h"/* Store at ubox	* It stores, creating the corresponding table if needed,	* the pair key/value in the corresponding ubox table*/static void storeatubox (lua_State* L, int lo){	#ifdef LUA_VERSION_NUM		lua_getfenv(L, lo);		if (lua_rawequal(L, -1, TOLUA_NOPEER)) {			lua_pop(L, 1);			lua_newtable(L);			lua_pushvalue(L, -1);			lua_setfenv(L, lo);	/* stack: k,v,table  */		};		lua_insert(L, -3);		lua_settable(L, -3); /* on lua 5.1, we trade the "tolua_peers" lookup for a settable call */		lua_pop(L, 1);	#else	 /* stack: key value (to be stored) */		lua_pushstring(L,"tolua_peers");		lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: k v ubox */		lua_pushvalue(L,lo);		lua_rawget(L,-2);                       /* stack: k v ubox ubox[u] */		if (!lua_istable(L,-1))		{			lua_pop(L,1);                          /* stack: k v ubox */			lua_newtable(L);                       /* stack: k v ubox table */			lua_pushvalue(L,1);			lua_pushvalue(L,-2);                   /* stack: k v ubox table u table */			lua_rawset(L,-4);                      /* stack: k v ubox ubox[u]=table */		}		lua_insert(L,-4);                       /* put table before k */		lua_pop(L,1);                           /* pop ubox */		lua_rawset(L,-3);                       /* store at table */		lua_pop(L,1);                           /* pop ubox[u] */	#endif}/* Module index function*/static int module_index_event (lua_State* L){	lua_pushstring(L,".get");	lua_rawget(L,-3);	if (lua_istable(L,-1))	{		lua_pushvalue(L,2);  /* key */		lua_rawget(L,-2);		if (lua_iscfunction(L,-1))		{			lua_call(L,0,1);			return 1;		}		else if (lua_istable(L,-1))			return 1;	}	/* call old index meta event */	if (lua_getmetatable(L,1))	{		lua_pushstring(L,"__index");		lua_rawget(L,-2);		lua_pushvalue(L,1);		lua_pushvalue(L,2);		if (lua_isfunction(L,-1))		{			lua_call(L,2,1);			return 1;		}		else if (lua_istable(L,-1))		{			lua_gettable(L,-3);			return 1;		}	}	lua_pushnil(L);	return 1;}/* Module newindex function*/static int module_newindex_event (lua_State* L){	lua_pushstring(L,".set");	lua_rawget(L,-4);	if (lua_istable(L,-1))	{		lua_pushvalue(L,2);  /* key */		lua_rawget(L,-2);		if (lua_iscfunction(L,-1))		{			lua_pushvalue(L,1); /* only to be compatible with non-static vars */			lua_pushvalue(L,3); /* value */			lua_call(L,2,0);			return 0;		}	}	/* call old newindex meta event */	if (lua_getmetatable(L,1) && lua_getmetatable(L,-1))	{		lua_pushstring(L,"__newindex");		lua_rawget(L,-2);		if (lua_isfunction(L,-1))		{		 lua_pushvalue(L,1);		 lua_pushvalue(L,2);		 lua_pushvalue(L,3);			lua_call(L,3,0);		}	}	lua_settop(L,3);	lua_rawset(L,-3);	return 0;}/* Class index function	* If the object is a userdata (ie, an object), it searches the field in	* the alternative table stored in the corresponding "ubox" table.*/static int class_index_event (lua_State* L){ int t = lua_type(L,1);	if (t == LUA_TUSERDATA)	{		/* Access alternative table */		#ifdef LUA_VERSION_NUM /* new macro on version 5.1 */		lua_getfenv(L,1);		if (!lua_rawequal(L, -1, TOLUA_NOPEER)) {			lua_pushvalue(L, 2); /* key */			lua_gettable(L, -2); /* on lua 5.1, we trade the "tolua_peers" lookup for a gettable call */			if (!lua_isnil(L, -1))				return 1;		};		#else		lua_pushstring(L,"tolua_peers");		lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: obj key ubox */		lua_pushvalue(L,1);		lua_rawget(L,-2);                       /* stack: obj key ubox ubox[u] */		if (lua_istable(L,-1))		{			lua_pushvalue(L,2);  /* key */			lua_rawget(L,-2);                      /* stack: obj key ubox ubox[u] value */			if (!lua_isnil(L,-1))				return 1;		}		#endif		lua_settop(L,2);                        /* stack: obj key */		/* Try metatables */		lua_pushvalue(L,1);                     /* stack: obj key obj */		while (lua_getmetatable(L,-1))		{                                       /* stack: obj key obj mt */			lua_remove(L,-2);                      /* stack: obj key mt */			if (lua_isnumber(L,2))                 /* check if key is a numeric value */			{				/* try operator[] */				lua_pushstring(L,".geti");				lua_rawget(L,-2);                      /* stack: obj key mt func */				if (lua_isfunction(L,-1))				{					lua_pushvalue(L,1);					lua_pushvalue(L,2);					lua_call(L,2,1);					return 1;				}			}			else			{			 lua_pushvalue(L,2);                    /* stack: obj key mt key */				lua_rawget(L,-2);                      /* stack: obj key mt value */				if (!lua_isnil(L,-1))					return 1;				else					lua_pop(L,1);				/* try C/C++ variable */				lua_pushstring(L,".get");				lua_rawget(L,-2);                      /* stack: obj key mt tget */				if (lua_istable(L,-1))				{					lua_pushvalue(L,2);					lua_rawget(L,-2);                      /* stack: obj key mt value */					if (lua_iscfunction(L,-1))					{						lua_pushvalue(L,1);						lua_pushvalue(L,2);						lua_call(L,2,1);						return 1;					}					else if (lua_istable(L,-1))					{						/* deal with array: create table to be returned and cache it in ubox */						void* u = *((void**)lua_touserdata(L,1));						lua_newtable(L);                /* stack: obj key mt value table */						lua_pushstring(L,".self");						lua_pushlightuserdata(L,u);						lua_rawset(L,-3);               /* store usertype in ".self" */						lua_insert(L,-2);               /* stack: obj key mt table value */						lua_setmetatable(L,-2);         /* set stored value as metatable */						lua_pushvalue(L,-1);            /* stack: obj key met table table */						lua_pushvalue(L,2);             /* stack: obj key mt table table key */						lua_insert(L,-2);               /*  stack: obj key mt table key table */						storeatubox(L,1);               /* stack: obj key mt table */						return 1;					}				}			}			lua_settop(L,3);		}		lua_pushnil(L);		return 1;	}	else if (t== LUA_TTABLE)	{		module_index_event(L);		return 1;	}	lua_pushnil(L);	return 1;}/* Newindex function	* It first searches for a C/C++ varaible to be set.	* Then, it either stores it in the alternative ubox table (in the case it is	* an object) or in the own table (that represents the class or module).*/static int class_newindex_event (lua_State* L){ int t = lua_type(L,1);	if (t == LUA_TUSERDATA)	{	 /* Try accessing a C/C++ variable to be set */		lua_getmetatable(L,1);		while (lua_istable(L,-1))                /* stack: t k v mt */		{			if (lua_isnumber(L,2))                 /* check if key is a numeric value */			{				/* try operator[] */				lua_pushstring(L,".seti");				lua_rawget(L,-2);                      /* stack: obj key mt func */				if (lua_isfunction(L,-1))				{					lua_pushvalue(L,1);					lua_pushvalue(L,2);					lua_pushvalue(L,3);					lua_call(L,3,0);					return 0;				}			}			else			{				lua_pushstring(L,".set");				lua_rawget(L,-2);                      /* stack: t k v mt tset */				if (lua_istable(L,-1))				{					lua_pushvalue(L,2);					lua_rawget(L,-2);                     /* stack: t k v mt tset func */					if (lua_iscfunction(L,-1))					{						lua_pushvalue(L,1);						lua_pushvalue(L,3);						lua_call(L,2,0);						return 0;					}					lua_pop(L,1);                          /* stack: t k v mt tset */				}				lua_pop(L,1);                           /* stack: t k v mt */				if (!lua_getmetatable(L,-1))            /* stack: t k v mt mt */					lua_pushnil(L);				lua_remove(L,-2);                       /* stack: t k v mt */			}		}	 lua_settop(L,3);                          /* stack: t k v */		/* then, store as a new field */		storeatubox(L,1);	}	else if (t== LUA_TTABLE)	{		module_newindex_event(L);	}	return 0;}static int class_call_event(lua_State* L) {	if (lua_istable(L, 1)) {		lua_pushstring(L, ".call");		lua_rawget(L, 1);		if (lua_isfunction(L, -1)) {			lua_insert(L, 1);			lua_call(L, lua_gettop(L)-1, 1);			return 1;		};	};	tolua_error(L,"Attempt to call a non-callable object.",NULL);	return 0;};static int do_operator (lua_State* L, const char* op){	if (lua_isuserdata(L,1))	{		/* Try metatables */		lua_pushvalue(L,1);                     /* stack: op1 op2 */		while (lua_getmetatable(L,-1))		{                                       /* stack: op1 op2 op1 mt */			lua_remove(L,-2);                      /* stack: op1 op2 mt */			lua_pushstring(L,op);                  /* stack: op1 op2 mt key */			lua_rawget(L,-2);                      /* stack: obj key mt func */			if (lua_isfunction(L,-1))			{				lua_pushvalue(L,1);				lua_pushvalue(L,2);				lua_call(L,2,1);				return 1;			}			lua_settop(L,3);		}	}	tolua_error(L,"Attempt to perform operation on an invalid operand",NULL);	return 0;}static int class_add_event (lua_State* L){	return do_operator(L,".add");}static int class_sub_event (lua_State* L){	return do_operator(L,".sub");}static int class_mul_event (lua_State* L){	return do_operator(L,".mul");}static int class_div_event (lua_State* L){	return do_operator(L,".div");}static int class_lt_event (lua_State* L){	return do_operator(L,".lt");}static int class_le_event (lua_State* L){	return do_operator(L,".le");}static int class_eq_event (lua_State* L){	return do_operator(L,".eq");}/*static int class_gc_event (lua_State* L){	void* u = *((void**)lua_touserdata(L,1));	fprintf(stderr, "collecting: looking at %p\n", u);	lua_pushstring(L,"tolua_gc");	lua_rawget(L,LUA_REGISTRYINDEX);	lua_pushlightuserdata(L,u);	lua_rawget(L,-2);	if (lua_isfunction(L,-1))	{		lua_pushvalue(L,1);		lua_call(L,1,0); 		lua_pushlightuserdata(L,u);		lua_pushnil(L);		lua_rawset(L,-3);	}	lua_pop(L,2);	return 0;}*/TOLUA_API int class_gc_event (lua_State* L){	void* u = *((void**)lua_touserdata(L,1));	int top;	/*fprintf(stderr, "collecting: looking at %p\n", u);*/	/*	lua_pushstring(L,"tolua_gc");	lua_rawget(L,LUA_REGISTRYINDEX);	*/	lua_pushvalue(L, lua_upvalueindex(1));	lua_pushlightuserdata(L,u);	lua_rawget(L,-2);            /* stack: gc umt    */	lua_getmetatable(L,1);       /* stack: gc umt mt */	/*fprintf(stderr, "checking type\n");*/	top = lua_gettop(L);	if (tolua_fast_isa(L,top,top-1, lua_upvalueindex(2))) /* make sure we collect correct type */	{		/*fprintf(stderr, "Found type!\n");*/		/* get gc function */		lua_pushliteral(L,".collector");		lua_rawget(L,-2);           /* stack: gc umt mt collector */		if (lua_isfunction(L,-1)) {			/*fprintf(stderr, "Found .collector!\n");*/		}		else {			lua_pop(L,1);			/*fprintf(stderr, "Using default cleanup\n");*/			lua_pushcfunction(L,tolua_default_collect);		}		lua_pushvalue(L,1);         /* stack: gc umt mt collector u */		lua_call(L,1,0);		lua_pushlightuserdata(L,u); /* stack: gc umt mt u */		lua_pushnil(L);             /* stack: gc umt mt u nil */		lua_rawset(L,-5);           /* stack: gc umt mt */	}	lua_pop(L,3);	return 0;}/* Register module events	* It expects the metatable on the top of the stack*/TOLUA_API void tolua_moduleevents (lua_State* L){	lua_pushstring(L,"__index");	lua_pushcfunction(L,module_index_event);	lua_rawset(L,-3);	lua_pushstring(L,"__newindex");	lua_pushcfunction(L,module_newindex_event);	lua_rawset(L,-3);}/* Check if the object on the top has a module metatable*/TOLUA_API int tolua_ismodulemetatable (lua_State* L){	int r = 0;	if (lua_getmetatable(L,-1))	{		lua_pushstring(L,"__index");		lua_rawget(L,-2);		r = (lua_tocfunction(L,-1) == module_index_event);		lua_pop(L,2);	}	return r;}/* Register class events	* It expects the metatable on the top of the stack*/TOLUA_API void tolua_classevents (lua_State* L){	lua_pushstring(L,"__index");	lua_pushcfunction(L,class_index_event);	lua_rawset(L,-3);	lua_pushstring(L,"__newindex");	lua_pushcfunction(L,class_newindex_event);	lua_rawset(L,-3);	lua_pushstring(L,"__add");	lua_pushcfunction(L,class_add_event);	lua_rawset(L,-3);	lua_pushstring(L,"__sub");	lua_pushcfunction(L,class_sub_event);	lua_rawset(L,-3);	lua_pushstring(L,"__mul");	lua_pushcfunction(L,class_mul_event);	lua_rawset(L,-3);	lua_pushstring(L,"__div");	lua_pushcfunction(L,class_div_event);	lua_rawset(L,-3);	lua_pushstring(L,"__lt");	lua_pushcfunction(L,class_lt_event);	lua_rawset(L,-3);	lua_pushstring(L,"__le");	lua_pushcfunction(L,class_le_event);	lua_rawset(L,-3);	lua_pushstring(L,"__eq");	lua_pushcfunction(L,class_eq_event);	lua_rawset(L,-3);	lua_pushstring(L,"__call");	lua_pushcfunction(L,class_call_event);	lua_rawset(L,-3);	lua_pushstring(L,"__gc");	lua_pushstring(L, "tolua_gc_event");	lua_rawget(L, LUA_REGISTRYINDEX);	/*lua_pushcfunction(L,class_gc_event);*/	lua_rawset(L,-3);}

⌨️ 快捷键说明

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