static void callLuaCB(Fl_Widget*w,void*toPair) {
    std::pair<std::string,int64_t>*p=(std::pair<std::string,int64_t>*)toPair;
    lua_getglobal(Lconf,p->first.c_str());
    lua_pushinteger(Lconf,p->second);
    runLuaFunc(Lconf,1,0);
}
Example #2
0
void LuaInterface::getGlobal(const std::string& key)
{
    lua_getglobal(L, key.c_str());
}
Example #3
0
bool CLuaEngine::RunLuaFunction(const char* szFunName,  const char* szTableName, const char* szSubTableName, 
					LuaParam * pInParam, int nInNum, LuaParam * pOutParam, int nOutNum)
{
	int top = lua_gettop(m_pLuaState);
	if( !szTableName )
	{
		lua_getglobal(m_pLuaState, szFunName);
	}
	else if( !szSubTableName )
	{
		lua_getglobal(m_pLuaState, szTableName);
		if( lua_istable(m_pLuaState, -1) )
		{
			lua_getfield(m_pLuaState,-1,szFunName);
		}
	}
	else
	{
		lua_getglobal(m_pLuaState, szTableName);
		if( lua_istable(m_pLuaState, -1) )
		{
			lua_getfield(m_pLuaState, -1, szSubTableName);
			if( lua_istable(m_pLuaState, -1) )
			{
				lua_getfield(m_pLuaState, -1, szFunName);
			}
		}

	}
	
	if( !lua_isfunction(m_pLuaState, -1) )
	{
		DEBUG_STROUT("[CLuaEngine] func not found:%s.%s", szTableName, szFunName);
		lua_settop(m_pLuaState, top);
		return false;
	}
	for(int i = 0; i < nInNum; i++)
	{
		switch(pInParam[i].Type())
		{
			case LUA_TNUMBER:				
				lua_pushnumber(m_pLuaState, *(lua_Number*)pInParam[i].Data());						
				break;			
			case LUA_TSTRING:
				lua_pushstring(m_pLuaState, (const char*)pInParam[i].Data());
				break;
			case LUA_TLIGHTUSERDATA:
				lua_pushlightuserdata(m_pLuaState, pInParam[i].Data());
				break;
			default:
				DEBUG_STROUT("[CLuaEngine] call func:%s.%s error:invalid input param", szTableName, szFunName);
				lua_settop(m_pLuaState, top);
				return false;
		}
	}
	if( !lua_pcall(m_pLuaState, nInNum, nOutNum, 0) )
	{
		for(int n = 0; n < nOutNum; n++)
		{
			int nType = lua_type(m_pLuaState, -1);
			switch(nType)
			{
				case LUA_TNUMBER:
					pOutParam[n].SetDataNum(lua_tonumber(m_pLuaState, -1));
					lua_pop(m_pLuaState, 1);
					break;
				case LUA_TBOOLEAN:
					pOutParam[n].SetDataNum(lua_toboolean(m_pLuaState, -1));
					lua_pop(m_pLuaState, 1);
					break;
				case LUA_TSTRING:
					pOutParam[n].SetDataString((const char*)lua_tostring(m_pLuaState, -1));
					lua_pop(m_pLuaState, 1);
					break;
				case LUA_TLIGHTUSERDATA:
					pOutParam[n].SetDataPointer((void*)lua_topointer(m_pLuaState, -1));
					lua_pop(m_pLuaState, 1);
					break;
				default:
					DEBUG_STROUT("[CLuaEngine] call func:%s.%s error:invalid output param", szTableName, szFunName);
					lua_settop(m_pLuaState, top);
					return false;					
			}
		}

		lua_settop(m_pLuaState, top);   //恢复栈成为未调用时的状态。
		return true;
	}	
	
	DEBUG_STROUT("[CLuaEngine] call func:%s.%s error:%s", szTableName, szFunName, GetLastError());
	lua_settop(m_pLuaState, top);
	return false;
}
Example #4
0
bool sinsp_chisel::parse_view_info(lua_State *ls, OUT chisel_desc* cd)
{
	lua_getglobal(ls, "view_info");
	if(lua_isnoneornil(ls, -1))
	{
		lua_close(ls);
		return false;
	}

	lua_pushnil(ls);

	string tmpstr;
	string id;
	string name;
	string description;
	vector<string> applies_to;
	string filter;
	bool use_defaults = false;
	sinsp_view_info::viewtype vt = sinsp_view_info::T_TABLE;
	vector<sinsp_view_column_info> columns;
	vector<string> tags;
	vector<string> tips;
	string drilldown_target;
	bool is_root = false;

	while(lua_next(ls, -2) != 0)
	{
		string fldname = lua_tostring(ls, -2);

		if(fldname == "name")
		{
			name = lua_tostring(ls, -1);
		}
		else if(fldname == "id")
		{
			id = lua_tostring(ls, -1);
		}
		else if(fldname == "description")
		{
			description = lua_tostring(ls, -1);
		}
		else if(fldname == "tags")
		{
			if(lua_istable(ls, -1))
			{
				lua_pushnil(ls);

				while(lua_next(ls, -2) != 0)
				{
					if(lua_isstring(ls, -1))
					{
						tmpstr = lua_tostring(ls, -1);
						tags.push_back(tmpstr);
					}
					else
					{
						throw sinsp_exception("error in view " + cd->m_name + ": " + "tags entries must be strings");
					}

					lua_pop(ls, 1);
				}
			}
			else
			{				
				throw sinsp_exception("error in view " + cd->m_name + ": " + string(lua_tostring(ls, -2)) + " is not a table");
			}
		}
		else if(fldname == "tips")
		{
			if(lua_istable(ls, -1))
			{
				lua_pushnil(ls);

				while(lua_next(ls, -2) != 0)
				{
					if(lua_isstring(ls, -1))
					{
						tmpstr = lua_tostring(ls, -1);
						tips.push_back(tmpstr);
					}
					else
					{
						throw sinsp_exception("error in view " + cd->m_name + ": " + "tips column entries must be strings");
					}

					lua_pop(ls, 1);
				}
			}
			else
			{				
				throw sinsp_exception("error in view " + cd->m_name + ": " + string(lua_tostring(ls, -2)) + " is not a table");
			}
		}
		else if(fldname == "view_type")
		{
			tmpstr = lua_tostring(ls, -1);

			if(tmpstr == "table")
			{
				vt = sinsp_view_info::T_TABLE;
			}
			else if(tmpstr == "list")
			{
				vt = sinsp_view_info::T_LIST;
			}
			else
			{
				throw sinsp_exception("error in view " + cd->m_name + ": " + string(lua_tostring(ls, -2)) + " must be either 'table' or 'list'");
			}
		}
		else if(fldname == "drilldown_target")
		{
			drilldown_target = lua_tostring(ls, -1);
		}
		else if(fldname == "applies_to")
		{
			if(lua_istable(ls, -1))
			{
				lua_pushnil(ls);

				while(lua_next(ls, -2) != 0)
				{
					if(lua_isstring(ls, -1))
					{
						tmpstr = lua_tostring(ls, -1);
						applies_to.push_back(tmpstr);
					}
					else
					{
						throw sinsp_exception("error in view " + cd->m_name + ": " + "tips column entries must be strings");
					}

					lua_pop(ls, 1);
				}
			}
			else
			{
				throw sinsp_exception("error in view " + cd->m_name + ": " + string(lua_tostring(ls, -2)) + " is not a table");
			}
		}
		else if(fldname == "filter")
		{
			filter = lua_tostring(ls, -1);
		}
		else if(fldname == "use_defaults")
		{
			if(lua_isboolean(ls, -1))
			{
				use_defaults = (lua_toboolean(ls, -1) != 0);
			}
			else
			{
				throw sinsp_exception("error in view " + cd->m_name + ": " + string(lua_tostring(ls, -2)) + " must be a boolean");
			}
		}
		else if(fldname == "is_root")
		{
			if(lua_isboolean(ls, -1))
			{
				is_root = (lua_toboolean(ls, -1) != 0);
			}
			else
			{
				throw sinsp_exception("error in view " + cd->m_name + ": " + string(lua_tostring(ls, -2)) + " must be a boolean");
			}
		}
		else if(fldname == "columns")
		{
			if(lua_istable(ls, -1))
			{
				parse_view_columns(ls, cd, &columns);
			}
			else
			{
				throw sinsp_exception("error in view " + cd->m_name + ": " + string(lua_tostring(ls, -2)) + " is not a table");
			}
		}

		lua_pop(ls, 1);
	}

	cd->m_viewinfo = sinsp_view_info(vt,
		id,
		name,
		description,
		tags,
		tips,
		columns,
		applies_to,
		filter,
		drilldown_target,
		use_defaults,
		is_root);

	return true;
}
Example #5
0
void sinsp_chisel::load(string cmdstr)
{
	m_filename = cmdstr;
	trim(cmdstr);

	ifstream is;

	//
	// Try to open the file as is
	//
	if(!openfile(m_filename, &is))
	{
		//
		// Try to add the .sc extension
		//
		if(!openfile(m_filename + ".sc", &is))
		{
			if(!openfile(m_filename + ".lua", &is))
			{
				throw sinsp_exception("can't open file " + m_filename);
			}
		}
	}

	//
	// Bring the file into a string
	//
	string docstr((istreambuf_iterator<char>(is)),
		istreambuf_iterator<char>());

#ifdef HAS_LUA_CHISELS
	//
	// Rewind the stream
	//
	is.seekg(0);

	//
	// Load the file
	//
	std::istreambuf_iterator<char> eos;
	std::string scriptstr(std::istreambuf_iterator<char>(is), eos);

	//
	// Open the script
	//
	m_ls = lua_open();
 
	luaL_openlibs(m_ls);

	//
	// Load our own lua libs
	//
	luaL_openlib(m_ls, "sysdig", ll_sysdig, 0);
	luaL_openlib(m_ls, "chisel", ll_chisel, 0);
	luaL_openlib(m_ls, "evt", ll_evt, 0);

	//
	// Add our chisel paths to package.path
	//
	for(uint32_t j = 0; j < g_chisel_dirs->size(); j++)
	{
		string path(g_chisel_dirs->at(j).m_dir);
		path += "?.lua";
		add_lua_package_path(m_ls, path.c_str());
	}

	//
	// Load the script
	//
	if(luaL_loadstring(m_ls, scriptstr.c_str()) || lua_pcall(m_ls, 0, 0, 0)) 
	{
		throw sinsp_exception("Failed to load chisel " + 
			m_filename + ": " + lua_tostring(m_ls, -1));
	}

	//
	// Allocate the chisel context for the script
	//
	m_lua_cinfo = new chiselinfo(m_inspector);

	//
	// Set the context globals
	//
	lua_pushlightuserdata(m_ls, this);
	lua_setglobal(m_ls, "sichisel");

	//
	// Extract the args
	//
	lua_getglobal(m_ls, "args");
	if(!lua_istable(m_ls, -1))
	{
		throw sinsp_exception("Failed to load chisel " + 
			m_filename + ": args table missing");
	}

	try
	{
		parse_lua_chisel_args(m_ls, &m_lua_script_info);
	}
	catch(sinsp_exception& e)
	{
		throw e;
	}

	//
	// Check if the script has an on_event
	//
	lua_getglobal(m_ls, "on_event");
	if(lua_isfunction(m_ls, -1))
	{
		m_lua_has_handle_evt = true;
		lua_pop(m_ls, 1);
	}
#endif

	is.close();
}
bool register_lua_bindings(lua_State* L, Scene* scene, GLFWwindow* window){

    maan::module_(L, "glm")
        //Register vec3
        .class_<glm::vec3>("vec3")
            .def_constructor<float, float, float>()
            .def_constructor<float>()
            .def_constructor<glm::vec3>()
            .def_operator<maan::add, glm::vec3>()
            .def_operator<maan::sub, glm::vec3>()
            .def_operator<maan::mul, glm::vec3>()
            .def_operator<maan::add, float>()
            .def_operator<maan::sub, float>()
            .def_operator<maan::mul, float>()
            .def_readwrite("x", &glm::vec3::x)
            .def_readwrite("y", &glm::vec3::y)
            .def_readwrite("z", &glm::vec3::z)
            .endef()
        .function_("cross", (glm::vec3 (*)(const glm::vec3&, const glm::vec3&)) glm::cross)
        .function_("dot", (float (*)(const glm::vec3&, const glm::vec3&)) glm::dot)
        .function_("normalize", (glm::vec3 (*)(const glm::vec3&)) glm::normalize)
        //Register vec4
        .class_<glm::vec4>("vec4")
            .def_constructor<float, float, float, float>()
            .def_constructor<float>()
            .def_constructor<glm::vec4>()
            .def_operator<maan::add, glm::vec4>()
            .def_operator<maan::sub, glm::vec4>()
            .def_operator<maan::mul, glm::vec4>()
            .def_operator<maan::add, float>()
            .def_operator<maan::sub, float>()
            .def_operator<maan::mul, float>()
            .def_readwrite("x", &glm::vec4::x)
            .def_readwrite("y", &glm::vec4::y)
            .def_readwrite("z", &glm::vec4::z)
            .def_readwrite("w", &glm::vec4::w)
            .endef()
        //TODO: Matrix access.
        .class_<glm::mat3>("mat3")
            .def_constructor<float>()
            .def_constructor<glm::mat3>()
            .def_constructor<glm::mat4>()
            .def_operator<maan::add, glm::mat3>()
            .def_operator<maan::sub, glm::mat3>()
            .def_operator<maan::mul, glm::mat3>()
            .def_operator<maan::mul, glm::vec3>()
            .def_operator<maan::add, float>()
            .def_operator<maan::sub, float>()
            .def_operator<maan::mul, float>()
            .endef()
        .function_("column", (glm::vec3 (*)(const glm::mat3&, int index)) glm::column)
        .function_("row", (glm::vec3 (*)(const glm::mat3&, int index)) glm::row)
        .function_("inverse", (glm::mat3 (*)(const glm::mat3&)) glm::inverse)
        .function_("transpose", (glm::mat3 (*)(const glm::mat3&)) glm::transpose)
        .class_<glm::mat4>("mat4")
            .def_constructor<float>()
            .def_constructor<glm::mat4>()
            .def_operator<maan::add, glm::mat4>()
            .def_operator<maan::sub, glm::mat4>()
            .def_operator<maan::mul, glm::mat4>()
            .def_operator<maan::mul, glm::vec4>()
            .def_operator<maan::add, float>()
            .def_operator<maan::sub, float>()
            .def_operator<maan::mul, float>()
            .endef()
        .function_("column", (glm::vec4 (*)(const glm::mat4&, int index)) glm::column)
        .function_("row", (glm::vec4 (*)(const glm::mat4&, int index)) glm::row)
        .function_("inverse", (glm::mat4 (*)(const glm::mat4&)) glm::inverse)
        .function_("transpose", (glm::mat4 (*)(const glm::mat4&)) glm::transpose);

    maan::module_(L, "scene")
        .class_<Particle>("Particle")
            .def_constructor<>()
            .def_constructor<const Particle&>()
            .def_readwrite("shape_id", &Particle::shape_id)
            .def_readwrite("rot", &Particle::rot)
            .def_readwrite("pos", &Particle::pos)
            .def_readwrite("size", &Particle::size)
            .endef()
        //Register shape
        .class_<Sphere>("Sphere")
            .def_constructor<>()
            .endef()
        //Register Mesh
        .class_<Mesh>("Mesh")
            .def_constructor<>()
            .def("add_vertex", &Mesh::add_vertex)
            .endef()
        .class_<Text::Properties>("TextProperties")
            .def_constructor<>()
            .def_constructor<const char*, float, const glm::vec4&, int, int>()
            .def_readwrite("color", &Text::Properties::color_)
            .def_readwrite("font", &Text::Properties::font_)
            .def_readwrite("width", &Text::Properties::width_)
            .def_readwrite("x", &Text::Properties::x_)
            .def_readwrite("y", &Text::Properties::y_)
            .endef()
        .function_("set_fov_degrees", &Scene::set_fov_degrees, scene)
        .function_("get_fov_degrees", &Scene::get_fov_degrees, scene)
        .function_("rotate", &Scene::rotate, scene)
        .function_("select_particle", &Scene::select_particle, scene)
        .function_("hide_particle", &Scene::hide_particle, scene)
        .function_("unhide_particle", &Scene::unhide_particle, scene)
        .function_("set_particle_color", &Scene::set_particle_color, scene)
        .function_("toggle_particle_point_drawing", &Scene::toggle_particle_point_drawing, scene)
        .function_("set_point_radius", &Scene::set_point_radius, scene)
        .function_("set_point_outline_radius", &Scene::set_point_outline_radius, scene)
        .function_("set_point_color", &Scene::set_point_color, scene)
        .function_("set_point_outline_color", &Scene::set_point_outline_color, scene)
        .function_("set_particle_selection_color", &Scene::set_particle_selection_color, scene)
        .function_("set_particle_selection_width_fraction", &Scene::set_particle_selection_width_fraction, scene)
        .function_("set_box_line_width", &Scene::set_box_line_width, scene)
        .function_("is_particle_selected", &Scene::is_particle_selected, scene)
        .function_("clear_particle_selections", &Scene::clear_particle_selections, scene)
        .function_("enable_clip_plane", &Scene::enable_clip_plane, scene)
        .function_("disable_clip_plane", &Scene::disable_clip_plane, scene)
        .function_("toggle_box", &Scene::toggle_box, scene)
        .function_("is_ssao_blur_enabled", &Scene::is_ssao_blur_enabled, scene)
        .function_("toggle_ssao_blur", &Scene::toggle_ssao_blur, scene)
        .function_("set_ssao_num_samples", &Scene::set_ssao_num_samples, scene)
        .function_("get_ssao_num_samples", &Scene::get_ssao_num_samples, scene)
        .function_("set_ssao_radius", &Scene::set_ssao_radius, scene)
        .function_("get_ssao_radius", &Scene::get_ssao_radius, scene)
        .function_("set_clip_plane", &Scene::set_clip_plane, scene)
        .function_("get_view_matrix", &Scene::get_view_matrix, scene)
        .function_("get_projection_matrix", &Scene::get_projection_matrix, scene)
        .function_("get_model_matrix", &Scene::get_model_matrix, scene)
        .function_("get_view_position", &Scene::get_view_position, scene)
        .function_("set_view_position", &Scene::set_view_position, scene)
        .function_("get_view_direction", &Scene::get_view_direction, scene)
        .function_("set_view_direction", &Scene::set_view_direction, scene)
        .function_("get_light_intensity", &Scene::get_light_intensity, scene)
        .function_("set_light_intensity", &Scene::set_light_intensity, scene)
        .function_("get_light_ambient_intensity", &Scene::get_light_ambient_intensity, scene)
        .function_("set_light_ambient_intensity", &Scene::set_light_ambient_intensity, scene)
        .function_("get_light_diffuse_intensity", &Scene::get_light_diffuse_intensity, scene)
        .function_("set_light_diffuse_intensity", &Scene::set_light_diffuse_intensity, scene)
        .function_("get_light_specular_intensity", &Scene::get_light_specular_intensity, scene)
        .function_("set_light_specular_intensity", &Scene::set_light_specular_intensity, scene)
        .function_("get_background_color", &Scene::get_background_color, scene)
        .function_("set_background_color", &Scene::set_background_color, scene)
        .function_("get_sky_color", &Scene::get_sky_color, scene)
        .function_("set_sky_color", &Scene::set_sky_color, scene)
        .function_("get_light_direction", &Scene::get_light_direction, scene)
        .function_("set_light_direction", &Scene::set_light_direction, scene)
        .function_("draw_text", &Scene::draw_text, scene)
        .function_("save_snapshot_png", &Scene::save_snapshot_png, scene);

#define ADD_CLASS_FUNCTION(cls, name)\
    {#name, lua ##cls##_##name},

    {
        luaL_Reg funcs[] = {
            ADD_CLASS_FUNCTION(Scene, load)
            ADD_CLASS_FUNCTION(Scene, raw_load)
            ADD_CLASS_FUNCTION(Scene, set_projection_type)
            ADD_CLASS_FUNCTION(Scene, raytrace)
            {NULL, NULL}
        };

        lua_getglobal(L, "scene");
        lua_pushlightuserdata(L, reinterpret_cast<void*>(scene));
        luaL_setfuncs(L, funcs, 1);
        lua_pop(L, 1);
    }

    {
        luaL_Reg funcs[] = {
            ADD_CLASS_FUNCTION(Window, size)
            ADD_CLASS_FUNCTION(Window, position)
            ADD_CLASS_FUNCTION(Window, set_size)
            ADD_CLASS_FUNCTION(Window, set_position)
            ADD_CLASS_FUNCTION(Window, set_title)
            {NULL, NULL}
        };

        lua_newtable(L);
        lua_pushvalue(L, -1);
        lua_setglobal(L, "window");

        lua_pushlightuserdata(L, window);
        luaL_setfuncs(L, funcs, 1);
        lua_pop(L, 1);

        register_keyboard_keys(L);
        register_mouse_buttons(L);
    }

    return true;
}
Example #7
0
void sinsp_chisel::on_init()
{
	//
	// Done with the arguments, call init()
	//
	lua_getglobal(m_ls, "on_init");

	if(!lua_isfunction(m_ls, -1)) 
	{
		//
		// No on_init. 
		// That's ok. Just return.
		//
		return;
	}

	if(lua_pcall(m_ls, 0, 1, 0) != 0) 
	{
		//
		// Exception running init
		//
		const char* lerr = lua_tostring(m_ls, -1);
		string err = m_filename + ": error in init(): " + lerr;
		throw sinsp_exception(err);
	}

	if(m_new_chisel_to_exec == "")
	{
		if(!lua_isboolean(m_ls, -1)) 
		{
			throw sinsp_exception(m_filename + " chisel error: wrong init() return value.");
		}

		if(!lua_toboolean(m_ls, -1))
		{
			throw sinsp_exception("init() for chisel " + m_filename + " failed.");
		}
	}

	lua_pop(m_ls, 1);

	//
	// If the chisel called chisel.exec(), free this chisel and load the new one
	//
	if(m_new_chisel_to_exec != "")
	{
		free_lua_chisel();
		load(m_new_chisel_to_exec);
		m_new_chisel_to_exec = "";

		string args;
		for(uint32_t j = 0; j < m_argvals.size(); j++)
		{
			if(m_argvals[j].find(" ") == string::npos)
			{
				args += m_argvals[j];
			}
			else
			{
				args += string("'") + m_argvals[j] + "'";
			}

			if(j < m_argvals.size() - 1)
			{
				args += " ";
			}
		}

		m_argvals.clear();
		set_args(args);

		on_init();
	}
}
Example #8
0
ApplicationBinder::ApplicationBinder(lua_State* L)
{
	Binder binder(L);

	static const luaL_Reg functionList[] = {
		{"openUrl", ApplicationBinder::openUrl},
		{"canOpenUrl", ApplicationBinder::canOpenUrl},
		{"getLogicalWidth", ApplicationBinder::getLogicalWidth},
		{"getLogicalHeight", ApplicationBinder::getLogicalHeight},
		{"getDeviceWidth", ApplicationBinder::getDeviceWidth},
		{"getDeviceHeight", ApplicationBinder::getDeviceHeight},
		{"vibrate", ApplicationBinder::vibrate},
		{"getLocale", ApplicationBinder::getLocale},
		{"getLanguage", ApplicationBinder::getLanguage},
		{"setKeepAwake", ApplicationBinder::setKeepAwake},
		{"getLogicalTranslateX", ApplicationBinder::getLogicalTranslateX},
		{"getLogicalTranslateY", ApplicationBinder::getLogicalTranslateY},
		{"getLogicalScaleX", ApplicationBinder::getLogicalScaleX},
		{"getLogicalScaleY", ApplicationBinder::getLogicalScaleY},
		{"getDeviceInfo", ApplicationBinder::getDeviceInfo},
		{"getContentWidth", ApplicationBinder::getContentWidth},
		{"getContentHeight", ApplicationBinder::getContentHeight},
		{"setBackgroundColor", ApplicationBinder::setBackgroundColor},
		{"getBackgroundColor", ApplicationBinder::getBackgroundColor},
		{"setOrientation", ApplicationBinder::setOrientation},
		{"getOrientation", ApplicationBinder::getOrientation},
        {"setScaleMode", ApplicationBinder::setScaleMode},
        {"getScaleMode", ApplicationBinder::getScaleMode},
        {"setLogicalDimensions", ApplicationBinder::setLogicalDimensions},
        {"setFps", ApplicationBinder::setFps},
        {"getFps", ApplicationBinder::getFps},
        {"exit", ApplicationBinder::exit},
        {"isPlayerMode", ApplicationBinder::isPlayerMode},
        {"getApiVersion", ApplicationBinder::getApiVersion},
        {"getTextureMemoryUsage", ApplicationBinder::getTextureMemoryUsage},
        {"getScreenDensity", ApplicationBinder::getScreenDensity},
        {"getDeviceOrientation", ApplicationBinder::getDeviceOrientation},
        {"configureFrustum", ApplicationBinder::configureFrustum},
        {"setWindowSize", ApplicationBinder::setWindowSize},
        {"setFullScreen", ApplicationBinder::setFullScreen},
        {"getDeviceName", ApplicationBinder::getDeviceName},
        {"set", ApplicationBinder::set},
        {"get", ApplicationBinder::get},
        {NULL, NULL},
	};

	binder.createClass("Application", NULL, 0, 0, functionList);

	lua_getglobal(L, "Application");

	lua_pushstring(L, PORTRAIT);
	lua_setfield(L, -2, "PORTRAIT");

	lua_pushstring(L, PORTRAIT_UPSIDE_DOWN);
	lua_setfield(L, -2, "PORTRAIT_UPSIDE_DOWN");

	lua_pushstring(L, LANDSCAPE_LEFT);
	lua_setfield(L, -2, "LANDSCAPE_LEFT");

	lua_pushstring(L, LANDSCAPE_RIGHT);
	lua_setfield(L, -2, "LANDSCAPE_RIGHT");

	lua_pop(L, 1);

	binder.pushInstance("Application", NULL);
	lua_setglobal(L, "application");
}
Example #9
0
/* Initialize the scripting environment.
 * It is possible to call this function to reset the scripting environment
 * assuming that we call scriptingRelease() before.
 * See scriptingReset() for more information. */
void scriptingInit(void) {
    lua_State *lua = lua_open();

    luaLoadLibraries(lua);
    luaRemoveUnsupportedFunctions(lua);

    /* Initialize a dictionary we use to map SHAs to scripts.
     * This is useful for replication, as we need to replicate EVALSHA
     * as EVAL, so we need to remember the associated script. */
    server.lua_scripts = dictCreate(&dbDictType,NULL);

    /* Register the redis commands table and fields */
    lua_newtable(lua);

    /* redis.call */
    lua_pushstring(lua,"call");
    lua_pushcfunction(lua,luaRedisCallCommand);
    lua_settable(lua,-3);

    /* redis.pcall */
    lua_pushstring(lua,"pcall");
    lua_pushcfunction(lua,luaRedisPCallCommand);
    lua_settable(lua,-3);

    /* redis.log and log levels. */
    lua_pushstring(lua,"log");
    lua_pushcfunction(lua,luaLogCommand);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_DEBUG");
    lua_pushnumber(lua,REDIS_DEBUG);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_VERBOSE");
    lua_pushnumber(lua,REDIS_VERBOSE);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_NOTICE");
    lua_pushnumber(lua,REDIS_NOTICE);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_WARNING");
    lua_pushnumber(lua,REDIS_WARNING);
    lua_settable(lua,-3);

    /* redis.sha1hex */
    lua_pushstring(lua, "sha1hex");
    lua_pushcfunction(lua, luaRedisSha1hexCommand);
    lua_settable(lua, -3);

    /* redis.error_reply and redis.status_reply */
    lua_pushstring(lua, "error_reply");
    lua_pushcfunction(lua, luaRedisErrorReplyCommand);
    lua_settable(lua, -3);
    lua_pushstring(lua, "status_reply");
    lua_pushcfunction(lua, luaRedisStatusReplyCommand);
    lua_settable(lua, -3);

    /* Finally set the table as 'redis' global var. */
    lua_setglobal(lua,"redis");

    /* Replace math.random and math.randomseed with our implementations. */
    lua_getglobal(lua,"math");

    lua_pushstring(lua,"random");
    lua_pushcfunction(lua,redis_math_random);
    lua_settable(lua,-3);

    lua_pushstring(lua,"randomseed");
    lua_pushcfunction(lua,redis_math_randomseed);
    lua_settable(lua,-3);

    lua_setglobal(lua,"math");

    /* Add a helper funciton that we use to sort the multi bulk output of non
     * deterministic commands, when containing 'false' elements. */
    {
        char *compare_func =    "function __redis__compare_helper(a,b)\n"
                                "  if a == false then a = '' end\n"
                                "  if b == false then b = '' end\n"
                                "  return a<b\n"
                                "end\n";
        luaL_loadbuffer(lua,compare_func,strlen(compare_func),"@cmp_func_def");
        lua_pcall(lua,0,0,0);
    }

    /* Create the (non connected) client that we use to execute Redis commands
     * inside the Lua interpreter.
     * Note: there is no need to create it again when this function is called
     * by scriptingReset(). */
    if (server.lua_client == NULL) {
        server.lua_client = createClient(-1);
        server.lua_client->flags |= REDIS_LUA_CLIENT;
    }

    /* Lua beginners ofter don't use "local", this is likely to introduce
     * subtle bugs in their code. To prevent problems we protect accesses
     * to global variables. */
    scriptingEnableGlobalsProtection(lua);

    server.lua = lua;
}
Example #10
0
static int
lua_general_handler(mtev_dso_generic_t *self) {
  int status, rv;
  lua_general_conf_t *conf = get_config(self);
  lua_module_closure_t *lmc = pthread_getspecific(conf->key);
  mtev_lua_resume_info_t *ri = NULL;
  const char *err = NULL;
  char errbuf[128];
  lua_State *L;

  if(!lmc) mtev_lua_general_init(self);
  lmc = pthread_getspecific(conf->key);
  if(!lmc || !conf || !conf->module || !conf->function) {
    goto boom;
  }
  ri = lua_general_new_resume_info(lmc);
  L = ri->coro_state;

  lua_getglobal(L, "require");
  lua_pushstring(L, conf->module);
  rv = lua_pcall(L, 1, 1, 0);
  if(rv) {
    int i;
    mtevL(nlerr, "lua: require %s failed\n", conf->module);
    mtev_lua_traceback(L);
    i = lua_gettop(L);
    if(i>0) {
      if(lua_isstring(L, i)) {
        const char *err;
        size_t len;
        err = lua_tolstring(L, i, &len);
        mtevL(nlerr, "lua: %s\n", err);
      }
    }
    lua_pop(L,i);
    goto boom;
  }
  lua_pop(L, lua_gettop(L));

  mtev_lua_pushmodule(L, conf->module);
  if(lua_isnil(L, -1)) {
    lua_pop(L, 1);
    snprintf(errbuf, sizeof(errbuf), "no such module: '%s'", conf->module);
    err = errbuf;
    goto boom;
  }
  lua_getfield(L, -1, conf->function);
  lua_remove(L, -2);
  if(!lua_isfunction(L, -1)) {
    lua_pop(L, 1);
    snprintf(errbuf, sizeof(errbuf), "no function '%s' in module '%s'",
             conf->function, conf->module);
    err = errbuf;
    goto boom;
  }

  status = lmc->resume(ri, 0);
  if(status == 0) return 0;
  /* If we've failed, resume has freed ri, so we should just return. */
  mtevL(nlerr, "lua dispatch error: %d\n", status);
  tragic_failure(self);
  return 0;

 boom:
  if(err) mtevL(nlerr, "lua dispatch error: %s\n", err);
  if(ri) lua_general_ctx_free(ri);
  tragic_failure(self);
  return 0;
}
Example #11
0
/**
 * Lua specific
 */
int my_lua_help(lua_State *state)
{
    bool has_sub = false;
    // implement help() in C so that we do not rely on the init to implement it
    // help can take optional arguments
    int n = lua_gettop(state);

    lua_getglobal(state, "hwstub");
    if(!lua_istable(state, -1))
        goto Lerr;
    lua_getfield(state, -1, "help");
    if(!lua_istable(state, -1))
        goto Lerr;

    for(int i = 1; i <= n; i++)
    {
        lua_pushvalue(state, i);
        lua_gettable(state, -2);
        if(lua_isnil(state, -1))
        {
            printf("I don't know subtopic '%s'!\n", lua_tostring(state, i));
            return 0;
        }
        if(!lua_istable(state, -1))
        {
            printf("Subtopic '%s' is not a table!\n", lua_tostring(state, i));
            return 0;
        }
    }

    printf("================[ HELP ");
    for(int i = 1; i <= n; i++)
        printf("> %s ", lua_tostring(state, i));
    printf("]================\n");

    lua_pushnil(state);
    while(lua_next(state, -2))
    {
        // key is at -2 and value at -1
        if(lua_isstring(state, -1))
            printf("%s\n", lua_tostring(state, -1));
        else if(lua_istable(state, -1))
            has_sub = true;
        // pop value but keep key
        lua_pop(state, 1);
    }

    if(has_sub)
    {
        printf("\n");
        printf("You can get more information on the following subtopics:\n");
        lua_pushnil(state);
        while(lua_next(state, -2))
        {
            // key is at -2 and value at -1
            if(lua_istable(state, -1))
                printf("* %s\n", lua_tostring(state, -2));
            // pop value but keep key
            lua_pop(state, 1);
        }
    }
    printf("================[ STOP ]================\n");

    return 0;

    Lerr:
    printf("There is a problem with the Lua context. Help is expected to be in hwstub.help\n");
    printf("You must have messed badly the environment.\n");
    return 0;
}
Example #12
0
void
luaH_add_paths(lua_State *L, const gchar *config_dir)
{
    lua_getglobal(L, "package");
    if(LUA_TTABLE != lua_type(L, 1)) {
        warn("package is not a table");
        return;
    }
    lua_getfield(L, 1, "path");
    if(LUA_TSTRING != lua_type(L, 2)) {
        warn("package.path is not a string");
        lua_pop(L, 1);
        return;
    }

    /* compile list of package search paths */
    GPtrArray *paths = g_ptr_array_new_with_free_func(g_free);

#if DEVELOPMENT_PATHS
    /* allows for testing luakit in the project directory */
    g_ptr_array_add(paths, g_strdup("./lib"));
    g_ptr_array_add(paths, g_strdup("./config"));
#endif

    /* add luakit install path */
    g_ptr_array_add(paths, g_build_filename(LUAKIT_INSTALL_PATH, "lib", NULL));

    /* add users config dir (see: XDG_CONFIG_DIR) */
    if (config_dir)
        g_ptr_array_add(paths, g_strdup(config_dir));

    /* add system config dirs (see: XDG_CONFIG_DIRS) */
    const gchar* const *config_dirs = g_get_system_config_dirs();
    for (; *config_dirs; config_dirs++)
        g_ptr_array_add(paths, g_build_filename(*config_dirs, "luakit", NULL));

    const gchar *path;
    for (guint i = 0; i < paths->len; i++) {
        path = paths->pdata[i];
        /* Search for file */
        lua_pushliteral(L, ";");
        lua_pushstring(L, path);
        lua_pushliteral(L, "/?.lua");
        lua_concat(L, 3);
        /* Search for lib */
        lua_pushliteral(L, ";");
        lua_pushstring(L, path);
        lua_pushliteral(L, "/?/init.lua");
        lua_concat(L, 3);
        /* concat with package.path */
        lua_concat(L, 3);
    }

    g_ptr_array_free(paths, TRUE);

    /* package.path = "concatenated string" */
    lua_setfield(L, 1, "path");

    /* remove package module from stack */
    lua_pop(L, 1);
}
Example #13
0
/*****************************************************************************
 * Called through lua_scripts_batch_execute to call 'probe' on
 * the script pointed by psz_filename.
 *****************************************************************************/
static int probe_luascript( vlc_object_t *p_this, const char * psz_filename,
                            const luabatch_context_t *p_context )
{
    VLC_UNUSED(p_context);
    demux_t * p_demux = (demux_t *)p_this;

    p_demux->p_sys->psz_filename = strdup(psz_filename);

    /* Initialise Lua state structure */
    lua_State *L = luaL_newstate();
    if( !L )
    {
        msg_Err( p_demux, "Could not create new Lua State" );
        goto error;
    }
    p_demux->p_sys->L = L;

    /* Load Lua libraries */
    luaL_openlibs( L ); /* FIXME: Don't open all the libs? */

    vlclua_set_this( L, p_demux );
    luaL_register( L, "vlc", p_reg );
    luaopen_msg( L );
    luaopen_strings( L );
    luaopen_stream( L );
    luaopen_variables( L );
    luaopen_xml( L );
    lua_pushstring( L, p_demux->psz_location );
    lua_setfield( L, -2, "path" );
    lua_pushstring( L, p_demux->psz_access );
    lua_setfield( L, -2, "access" );

    lua_pop( L, 1 );

    /* Setup the module search path */
    if( vlclua_add_modules_path( L, psz_filename ) )
    {
        msg_Warn( p_demux, "Error while setting the module search path for %s",
                  psz_filename );
        goto error;
    }

    /* Load and run the script(s) */
    if( vlclua_dofile( VLC_OBJECT(p_demux), L, psz_filename ) )
    {
        msg_Warn( p_demux, "Error loading script %s: %s", psz_filename,
                  lua_tostring( L, lua_gettop( L ) ) );
        goto error;
    }

    lua_getglobal( L, "probe" );

    if( !lua_isfunction( L, -1 ) )
    {
        msg_Warn( p_demux, "Error while running script %s, "
                  "function probe() not found", psz_filename );
        goto error;
    }

    if( lua_pcall( L, 0, 1, 0 ) )
    {
        msg_Warn( p_demux, "Error while running script %s, "
                  "function probe(): %s", psz_filename,
                  lua_tostring( L, lua_gettop( L ) ) );
        goto error;
    }

    if( lua_gettop( L ) )
    {
        if( lua_toboolean( L, 1 ) )
        {
            msg_Dbg( p_demux, "Lua playlist script %s's "
                     "probe() function was successful", psz_filename );
            lua_pop( L, 1 );
            return VLC_SUCCESS;
        }
    }

error:
    lua_pop( L, 1 );
    lua_close( p_demux->p_sys->L );
    p_demux->p_sys->L = NULL;
    FREENULL( p_demux->p_sys->psz_filename );
    return VLC_EGENERIC;
}
void editor::_editor() {
    //create the window
    keepUserdat=new std::vector<std::pair<unsigned,int64_t>>;
    luaCallback=new std::vector<std::pair<std::string,int64_t>>;
    startLuaConf();
    menu = new Fl_Menu_Bar(0,0,800,24);//Create menubar, items..
    lua_getglobal(Lconf,"generateMenu");
    runLuaFunc(Lconf,0,1);
    {   unsigned menucnt;
        std::vector<Fl_Menu_Item> tmp;
        if(!(menucnt=lua_rawlen(Lconf,-1))) {
            fl_alert("generateMenu must return a table");
            exit(1);
        }
        for(unsigned i=1; i<=menucnt; ++i) {
            lua_rawgeti(Lconf,-1,i);
            unsigned len=lua_rawlen(Lconf,-1);
            if(len) {
                Fl_Menu_Item mi{0};
                lua_rawgeti(Lconf,-1,1);
                char*txt=(char*)luaL_optstring(Lconf,-1,0);
                if(txt)
                    txt=strdup(txt);
                mi.text=txt;
                lua_pop(Lconf,1);
                if(len>=2) {
                    lua_rawgeti(Lconf,-1,2);
                    mi.shortcut_=luaL_optinteger(Lconf,-1,0);
                    lua_pop(Lconf,1);
                } else
                    mi.shortcut_=0;
                int64_t userdat;
                if(len>=4) {
                    lua_rawgeti(Lconf,-1,4);
                    userdat=luaL_optinteger(Lconf,-1,0);
                    lua_pop(Lconf,1);
                } else
                    userdat=0;

                if(len>=3) {
                    lua_rawgeti(Lconf,-1,3);
                    if(lua_type(Lconf,-1)==LUA_TSTRING) {
                        luaCallback->emplace_back(std::make_pair(lua_tostring(Lconf,-1),userdat));
                        mi.callback_=callLuaCB;
                        mi.user_data_=&(*luaCallback)[luaCallback->size()-1];
                    } else if(lua_type(Lconf,-1)==LUA_TNUMBER) {
                        int64_t lcall=lua_tointeger(Lconf,-1);
                        if(lcall>0) {
                            keepUserdat->emplace_back(std::make_pair(lcall-1,userdat));
                            mi.callback_=callCFuncLua;
                            mi.user_data_=&(*keepUserdat)[keepUserdat->size()-1];
                        } else
                            mi.callback_=0;
                    } else {
                        fl_alert("Error invalid type for callback %s",lua_typename(Lconf,lua_type(Lconf,-1)));
                        exit(1);
                    }
                    lua_pop(Lconf,1);
                } else {
                    mi.callback_=0;
                    mi.user_data_=0;
                }
                if(len>=5) {
                    lua_rawgeti(Lconf,-1,5);
                    mi.flags=luaL_optinteger(Lconf,-1,0);
                    lua_pop(Lconf,1);
                } else
                    mi.flags=0;
                tmp.emplace_back(mi);
            } else
                tmp.emplace_back(Fl_Menu_Item{0});
            lua_pop(Lconf,1);
        }
        unsigned cidx=0,lidx=0;
        for(unsigned i=0; i<menucnt; ++i) { //While resizing the vector the addresses may have changed.
            lua_rawgeti(Lconf,-1,i+1);
            unsigned len=lua_rawlen(Lconf,-1);
            if(len>=3) {
                lua_rawgeti(Lconf,-1,3);
                if(lua_type(Lconf,-1)==LUA_TSTRING) {
                    tmp[i].user_data_=&(*luaCallback)[lidx++];
                } else if(lua_type(Lconf,-1)==LUA_TNUMBER) {
                    int64_t lcall=lua_tointeger(Lconf,-1);
                    if(lcall>0)
                        tmp[i].user_data_=&(*keepUserdat)[cidx++];
                }
                lua_pop(Lconf,1);
            }
            lua_pop(Lconf,1);
        }
        lua_pop(Lconf,1);
        menu->copy(tmp.data());
    }
    tile_placer_tile_offset_y=default_tile_placer_tile_offset_y;
    true_color_box_x=default_true_color_box_x;
    true_color_box_y=default_true_color_box_y;
    tile_edit_truecolor_off_x=default_tile_edit_truecolor_off_x;
    tile_edit_truecolor_off_y=default_tile_edit_truecolor_off_y;
    std::fill(tabsHidden,&tabsHidden[shareAmtPj],false);
    {
        the_tabs = new Fl_Tabs(0, 24, 800, 576);
        the_tabs->callback(set_mode_tabs);
        int rx,ry,rw,rh;
        the_tabs->client_area(rx,ry,rw,rh);
        {
            tabsMain.emplace_back(new Fl_Group(rx, ry, rw, rh, "Palette editor"));
            //stuff related to this group should go here
            palBar.addTab(0,true);
            pal_size = new Fl_Hor_Value_Slider(128,384,320,24,"Palette box size");
            pal_size->minimum(1);
            pal_size->maximum(42);
            pal_size->step(1);
            pal_size->value(32);
            pal_size->align(FL_ALIGN_LEFT);
            pal_size->callback(redrawOnlyCB);
            ditherPower = new Fl_Hor_Value_Slider(128,416,320,24,"Dither Power");
            ditherPower->tooltip("A lower value results in more dithering artifacts a higher value results in less artifacts");
            ditherPower->minimum(1);
            ditherPower->maximum(256);
            ditherPower->step(1);
            ditherPower->value(16);
            ditherPower->align(FL_ALIGN_LEFT);
            ditherPower->callback(setSubditherSetting);
            gameSysSel=new Fl_Choice(96, 312, 192, 24);
            gameSysSel->copy(gameSysMenuSel);
            ditherAlgSel=new Fl_Choice(64, 464, 144, 24);
            ditherAlgSel->copy(ditherChoices);
            subSysC=new Fl_Choice(208, 464, 128, 24);
            subSysC->copy(subSysGenesis);
            subSysC->value(0);
            {   Fl_Group *o = new Fl_Group(306, 188, 88, 96);
                {
                    palType[0] = new Fl_Round_Button(306, 188, 64, 32, "Free");
                    palType[0]->type(FL_RADIO_BUTTON);
                    palType[0]->set();
                    palType[0]->callback((Fl_Callback*) setPalType,(void *)0);
                    palType[0]->tooltip(freeDes);
                    palType[1] = new Fl_Round_Button(306, 220, 72, 32, "Locked");
                    palType[1]->type(FL_RADIO_BUTTON);
                    palType[1]->callback((Fl_Callback*) setPalType,(void *)1);
                    palType[1]->tooltip(lockedDes);
                    palType[2] = new Fl_Round_Button(306, 252, 88, 32, "Reserved");
                    palType[2]->type(FL_RADIO_BUTTON);
                    palType[2]->callback((Fl_Callback*) setPalType,(void *)2);
                    palType[2]->tooltip(reservedDes);
                    o->end();
                } // End of buttons
            }//end of group

            lua_getglobal(Lconf,"tabConfig");
            lua_pushinteger(Lconf,pal_edit);
            runLuaFunc(Lconf,1,0);

            tabsMain[pal_edit]->end();
        } // Fl_Group* o
        {   tabsMain.emplace_back(new Fl_Group(rx, ry, rw, rh, "Tile editor"));
            //stuff related to this group should go here
            {   Fl_Group* o = new Fl_Group(0, 0, 800, 567);
                palRTE[0] = new Fl_Round_Button(384, default_palette_bar_offset_y+40, 56, 32, "Row 0");
                palRTE[0]->type(FL_RADIO_BUTTON);
                palRTE[0]->set();
                palRTE[0]->callback((Fl_Callback*) set_tile_row,(void *)0);
                palRTE[1] = new Fl_Round_Button(448, default_palette_bar_offset_y+40, 56, 32, "Row 1");
                palRTE[1]->type(FL_RADIO_BUTTON);
                palRTE[1]->callback((Fl_Callback*) set_tile_row,(void *)1);
                palRTE[2] = new Fl_Round_Button(512, default_palette_bar_offset_y+40, 56, 32, "Row 2");
                palRTE[2]->type(FL_RADIO_BUTTON);
                palRTE[2]->callback((Fl_Callback*) set_tile_row,(void *)2);
                palRTE[3] = new Fl_Round_Button(576, default_palette_bar_offset_y+40, 56, 32, "Row 3");
                palRTE[3]->type(FL_RADIO_BUTTON);
                palRTE[3]->callback((Fl_Callback*) set_tile_row,(void *)3);
                o->end();
            } // Fl_Group* o
            {   Fl_Button *o = new Fl_Button(538, default_palette_bar_offset_y, 104, 32, "Append tile");//these button should be inline with the palette bar
                o->tooltip("This will append a blank tile to the tile buffer in the ram.");
                o->callback(new_tile);
            }
            {   Fl_Button *o = new Fl_Button(656, default_palette_bar_offset_y, 140, 32, "Delete selected tile");
                o->tooltip("This button will delete the currently selected tile");
                o->callback(delete_tile_at_location);
                o->labelsize(12);
            }
            {   Fl_Button *o = new Fl_Button(656, default_palette_bar_offset_y+34,140, 32,"Insert after tile");
                o->callback(insertTileCB);
            }
            palBar.addTab(1);
            rgb_red = new Fl_Hor_Value_Slider(64,default_palette_bar_offset_y+136,128,24,"RGB red");
            rgb_red->minimum(0);
            rgb_red->maximum(255);
            rgb_red->step(1);
            rgb_red->value(0);
            rgb_red->align(FL_ALIGN_LEFT);
            rgb_red->callback(update_truecolor,(void *)0);
            rgb_green = new Fl_Hor_Value_Slider(240,default_palette_bar_offset_y+136,128,24,"Green");
            rgb_green->minimum(0);
            rgb_green->maximum(255);
            rgb_green->step(1);
            rgb_green->value(0);
            rgb_green->align(FL_ALIGN_LEFT);
            rgb_green->callback(update_truecolor,(void *)1);
            rgb_blue = new Fl_Hor_Value_Slider(402,default_palette_bar_offset_y+136,128,24,"Blue");
            rgb_blue->minimum(0);
            rgb_blue->maximum(255);
            rgb_blue->step(1);
            rgb_blue->value(0);
            rgb_blue->align(FL_ALIGN_LEFT);
            rgb_blue->callback(update_truecolor,(void *)2);
            rgb_alpha = new Fl_Hor_Value_Slider(576,default_palette_bar_offset_y+136,128,24,"Alpha");
            rgb_alpha->minimum(0);
            rgb_alpha->maximum(255);
            rgb_alpha->step(1);
            rgb_alpha->value(0);
            rgb_alpha->align(FL_ALIGN_LEFT);
            rgb_alpha->callback(update_truecolor,(void *)3);
            {   Fl_Group *o = new Fl_Group(304, 96, 88, 96);
                {
                    palType[3] = new Fl_Round_Button(304, 96, 64, 32, "Free");
                    palType[3]->type(FL_RADIO_BUTTON);
                    palType[3]->set();
                    palType[3]->callback((Fl_Callback*) setPalType,(void *)0);
                    palType[3]->tooltip(freeDes);
                    palType[4] = new Fl_Round_Button(304, 128, 72, 32, "Locked");
                    palType[4]->type(FL_RADIO_BUTTON);
                    palType[4]->callback((Fl_Callback*) setPalType,(void *)1);
                    palType[4]->tooltip(lockedDes);
                    palType[5] = new Fl_Round_Button(304, 160, 88, 32, "Reserved");
                    palType[5]->type(FL_RADIO_BUTTON);
                    palType[5]->callback((Fl_Callback*) setPalType,(void *)2);
                    palType[5]->tooltip(reservedDes);
                    o->end();
                } // End of buttons
            }//end of group
            {   Fl_Check_Button* o = new Fl_Check_Button(694,default_palette_bar_offset_y+68,100,32,"Show grid?");
                o->callback(set_grid);
                o->tooltip("This button Toggles weather or not you which to see a grid while editing your tiles. A grid can help you see the spacing between each pixel.");
            }
            tile_edit_offset_x=default_tile_edit_offset_x;
            tile_edit_offset_y=default_tile_edit_offset_y;
            tile_size = new Fl_Hor_Value_Slider(448,default_palette_bar_offset_y+72,242,24,"Tile zoom");
            tile_size->tooltip(TooltipZoom);
            tile_size->minimum(1);
            tile_size->maximum(64);
            tile_size->step(1);
            tile_size->value(46);
            tile_size->align(FL_ALIGN_LEFT);
            tile_size->callback(update_offset_tile_edit);
            //now for the tile select slider
            tile_select = new Fl_Hor_Value_Slider(480,default_palette_bar_offset_y+104,312,24,"Tile select");
            tile_select->tooltip("This slider selects which tile that you are editing the first tile is zero");
            tile_select->minimum(0);
            tile_select->maximum(0);
            tile_select->step(1);
            tile_select->align(FL_ALIGN_LEFT);
            tile_select->callback(set_tile_current);
            lua_getglobal(Lconf,"tabConfig");
            lua_pushinteger(Lconf,tile_edit);
            runLuaFunc(Lconf,1,0);
            tabsMain[tile_edit]->end();
        }
        {   tabsMain.emplace_back(new Fl_Group(rx,ry,rw,rh,"Plane mapping/block editor"));
            {   Fl_Group* o = new Fl_Group(tile_place_buttons_x_off, 192, 60, 128);
                palRTE[4] = new Fl_Round_Button(tile_place_buttons_x_off, 192, 60, 28, "Row 0");
                palRTE[4]->type(FL_RADIO_BUTTON);
                palRTE[4]->set();
                palRTE[4]->callback((Fl_Callback*) set_tile_row,(void *)0);
                palRTE[5] = new Fl_Round_Button(tile_place_buttons_x_off, 220, 60, 28, "Row 1");
                palRTE[5]->type(FL_RADIO_BUTTON);
                palRTE[5]->callback((Fl_Callback*) set_tile_row,(void *)1);
                palRTE[6] = new Fl_Round_Button(tile_place_buttons_x_off, 248, 60, 28, "Row 2");
                palRTE[6]->type(FL_RADIO_BUTTON);
                palRTE[6]->callback((Fl_Callback*) set_tile_row,(void *)2);
                palRTE[7] = new Fl_Round_Button(tile_place_buttons_x_off, 276, 60, 28, "Row 3");
                palRTE[7]->type(FL_RADIO_BUTTON);
                palRTE[7]->callback((Fl_Callback*) set_tile_row,(void *)3);
                o->end();
            } // Fl_Group* o


            planeSelect=new Fl_Choice(408,default_palette_bar_offset_y+56,112,24,"Plane selection");
            planeSelect->align(FL_ALIGN_TOP);

            {   Fl_Button *o = new Fl_Button(408, default_palette_bar_offset_y+80,112,24,"Add plane");
                o->callback(addPlaneTilemap);
            }

            {   Fl_Button *o = new Fl_Button(408, default_palette_bar_offset_y+104,112,24,"Remove plane");
                o->callback(removeTilemapsPlane);
            }

            curPlaneName = new Fl_Input(tile_place_buttons_x_off+616,56,168,24,"Plane name");
            curPlaneName->value("0");
            curPlaneName->callback(updateNameTilemaps);

            map_w = new Fl_Int_Input(608,default_palette_bar_offset_y+72,184,24,MapWidthTxt);
            map_w->when(FL_WHEN_ENTER_KEY);
            map_w->value("2");
            map_w->align(FL_ALIGN_LEFT);
            map_w->callback(callback_resize_map);
            map_h = new Fl_Int_Input(608,default_palette_bar_offset_y+104,184,24,MapHeightTxt);
            map_h->when(FL_WHEN_ENTER_KEY);
            map_h->value("2");
            map_h->align(FL_ALIGN_LEFT);
            map_h->callback(callback_resize_map);
            map_amt = new Fl_Int_Input(480,default_palette_bar_offset_y+136,312,24,"Blocks");
            map_amt->value("1");
            map_amt->align(FL_ALIGN_LEFT);
            map_amt->callback(blocksAmtCB);
            map_amt->hide();
            map_x_scroll = new Fl_Scrollbar(default_map_off_x-32, default_map_off_y-32, 800-8-default_map_off_x, 24);
            map_x_scroll->value(0,0,0,0);
            map_x_scroll->type(FL_HORIZONTAL);
            map_x_scroll->tooltip("Use this scroll bar to move around the tile map if you are zoomed in and there is not enough room to display the entire tilemap at once. This scroll bar will move the map left and right.");
            map_x_scroll->callback(update_map_scroll_x);
            map_x_scroll->hide();
            map_x_scroll->linesize(1);
            map_y_scroll = new Fl_Scrollbar(default_map_off_x-32, default_map_off_y, 24, 600-8-default_map_off_y);
            map_y_scroll->value(0,0,0,0);
            //map_x_scroll->type(FL_HORIZONTAL);
            map_y_scroll->tooltip("Use this scroll bar to move around the tile map if you are zoomed in and there is not enough room to display the entire tilemap at once. This scroll bar will move the map up and down.");
            map_y_scroll->callback(update_map_scroll_y);
            map_y_scroll->hide();
            map_y_scroll->linesize(1);
            //now for the tile select slider
            tile_select_2 = new Fl_Hor_Value_Slider(528,default_palette_bar_offset_y+40,264,24,"Tile select");
            tile_select_2->tooltip("This slider allows you to choice which tile you would like to place on the map remember you can both horizontally and vertically flip the tile once placed on the map and select which row the tile uses");
            tile_select_2->minimum(0);
            tile_select_2->maximum(0);
            tile_select_2->step(1);
            tile_select_2->align(FL_ALIGN_TOP_LEFT);
            tile_select_2->callback(set_tile_currentTP);
            totalTiles=new Fl_Box(600,default_palette_bar_offset_y,128,64);
            totalTiles->labelsize(12);
            palBar.addTab(2);
            //buttons for tile settings
            {   Fl_Group *o = new Fl_Group(304, 96, 88, 96);
                {
                    palType[6] = new Fl_Round_Button(304, 90, 64, 32, "Free");
                    palType[6]->type(FL_RADIO_BUTTON);
                    palType[6]->set();
                    palType[6]->callback((Fl_Callback*) setPalType,(void *)0);
                    palType[6]->tooltip(freeDes);
                    palType[7] = new Fl_Round_Button(304, 122, 72, 32, "Locked");
                    palType[7]->type(FL_RADIO_BUTTON);
                    palType[7]->callback((Fl_Callback*) setPalType,(void *)1);
                    palType[7]->tooltip(lockedDes);
                    palType[8] = new Fl_Round_Button(304, 154, 88, 32, "Reserved");
                    palType[8]->type(FL_RADIO_BUTTON);
                    palType[8]->callback((Fl_Callback*) setPalType,(void *)2);
                    palType[8]->tooltip(reservedDes);
                    o->end();
                } // End of buttons
            }//end of group

            hflipCB[0] = new Fl_Check_Button(tile_place_buttons_x_off,304,64,32,"Hflip");
            hflipCB[0]->callback(set_hflipCB,(void*)0);
            hflipCB[0]->tooltip("This sets whether or not the tile is flipped horizontally");
            vflipCB[0] = new Fl_Check_Button(tile_place_buttons_x_off,336,64,32,"Vflip");
            vflipCB[0]->callback(set_vflipCB,(void*)0);
            vflipCB[0]->tooltip("This sets whether or not the tile is flipped vertically");
            prioCB[0] = new Fl_Check_Button(tile_place_buttons_x_off,368,72,32,"Priority");
            prioCB[0]->callback(set_prioCB,(void*)0);
            prioCB[0]->tooltip("If checked tile is high priority");
            {   Fl_Check_Button* o = new Fl_Check_Button(tile_place_buttons_x_off,400,96,32,"Show grid?");
                o->callback(set_grid_placer);
                o->tooltip("This button toggles whether or not a grid is visible over the tile map this will allow you to easily see were each tile is");
            }
            BlocksCBtn = new Fl_Check_Button(tile_place_buttons_x_off,432,96,32,"Blocks?");
            BlocksCBtn->callback(toggleBlocksCB);
            BlocksCBtn->tooltip("Toggles if tile map is treated as blocks");
            {   Fl_Check_Button* o = new Fl_Check_Button(tile_place_buttons_x_off,464,192,32,"Show only selected row");
                o->callback(toggleRowSolo);
                o->tooltip("When checked tiles that do not use the selected row will not be drawn");
            }
            place_tile_size = new Fl_Hor_Value_Slider(tile_place_buttons_x_off,512,168,24,"Tile zoom factor:");
            place_tile_size->minimum(1);
            place_tile_size->maximum(16);
            place_tile_size->step(1);
            place_tile_size->value(12);
            place_tile_size->align(FL_ALIGN_TOP);
            place_tile_size->callback(update_map_size);
            place_tile_size->tooltip(TooltipZoom);

            tmapOffset = new Fl_Int_Input(tile_place_buttons_x_off,552,168,24,"Tile offset");
            tmapOffset->when(FL_WHEN_ENTER_KEY);
            tmapOffset->value("0");
            tmapOffset->align(FL_ALIGN_TOP);
            tmapOffset->callback(setTmapOffsetCB);

            cordDisp[0]=new Fl_Box(tile_place_buttons_x_off,556,128,64);
            cordDisp[0]->labelsize(12);

            lua_getglobal(Lconf,"tabConfig");
            lua_pushinteger(Lconf,tile_place);
            runLuaFunc(Lconf,1,0);
            tabsMain[tile_place]->end();
        }
        {   tabsMain.emplace_back(new Fl_Group(rx,ry,rw,rh,"Chunk editor"));
            useBlocksChunkCBtn=new Fl_Check_Button(8, 48, 152, 24, "Use blocks");
            useBlocksChunkCBtn->callback(useBlocksCB);

            chunkX = new Fl_Scrollbar(DefaultChunkX-32, DefaultChunkY-32, 800-DefaultChunkX+24, 24);
            chunkX->value(0,0,0,0);
            chunkX->type(FL_HORIZONTAL);
            chunkX->callback(scrollChunkX);
            chunkX->hide();

            chunkY = new Fl_Scrollbar(DefaultChunkX-32, DefaultChunkY, 24, 600-8-DefaultChunkY);
            chunkY->value(0,0,0,0);
            chunkY->callback(scrollChunkY);
            chunkY->hide();

            chunk_select = new Fl_Hor_Value_Slider(tile_place_buttons_x_off,88,160,24,"Chunk select");
            chunk_select->minimum(0);
            chunk_select->maximum(0);
            chunk_select->step(1);
            chunk_select->value(0);
            chunk_select->align(FL_ALIGN_TOP);
            chunk_select->callback(currentChunkCB);

            tile_select_3 = new Fl_Hor_Value_Slider(tile_place_buttons_x_off,136,160,24,"Tile select");
            tile_select_3->minimum(0);
            tile_select_3->maximum(0);
            tile_select_3->step(1);
            tile_select_3->align(FL_ALIGN_TOP);
            tile_select_3->callback(selBlockCB);

            hflipCB[1] = new Fl_Check_Button(tile_place_buttons_x_off,160,64,32,"Hflip");
            hflipCB[1]->callback(set_hflipCB,(void*)1);
            vflipCB[1] = new Fl_Check_Button(tile_place_buttons_x_off,192,64,32,"Vflip");
            vflipCB[1]->callback(set_vflipCB,(void*)1);
            prioCB[1] = new Fl_Check_Button(tile_place_buttons_x_off,224,72,32,"Priority");
            prioCB[1]->callback(set_prioCB,(void*)1);

            solidChunkMenu=new Fl_Choice(tile_place_buttons_x_off,256,128,24);
            solidChunkMenu->copy(SolidMenu);

            chunksize[0]=new Fl_Int_Input(tile_place_buttons_x_off,296,128,24,"Width (in tiles)");
            chunksize[0]->when(FL_WHEN_ENTER_KEY);
            chunksize[0]->align(FL_ALIGN_TOP);
            chunksize[0]->callback(resizeChunkCB);
            chunksize[0]->value("16");

            chunksize[1]=new Fl_Int_Input(tile_place_buttons_x_off,336,128,24,"Height (in tiles)");
            chunksize[1]->when(FL_WHEN_ENTER_KEY);
            chunksize[1]->align(FL_ALIGN_TOP);
            chunksize[1]->callback(resizeChunkCB);
            chunksize[1]->value("16");

            planeSelectChunk = new Fl_Hor_Value_Slider(tile_place_buttons_x_off,480,160,24,"Plane select");
            planeSelectChunk->minimum(0);
            planeSelectChunk->maximum(0);
            planeSelectChunk->step(1);
            planeSelectChunk->align(FL_ALIGN_TOP);
            planeSelectChunk->callback(setCurPlaneChunkCB);

            chunk_tile_size = new Fl_Hor_Value_Slider(tile_place_buttons_x_off,520,160,24,"Tile zoom factor:");
            chunk_tile_size->minimum(1);
            chunk_tile_size->maximum(16);
            chunk_tile_size->step(1);
            chunk_tile_size->value(2);
            chunk_tile_size->align(FL_ALIGN_TOP);
            chunk_tile_size->callback(scrollChunkCB);
            chunk_tile_size->tooltip(TooltipZoom);

            cordDisp[1]=new Fl_Box(tile_place_buttons_x_off,556,128,64);
            cordDisp[1]->labelsize(12);

            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off,364, 112, 32, "Append chunk");
                o->callback(appendChunkCB);
            }

            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off,396, 128, 32, "Insert after chunk");
                o->callback(insertChunkCB);
            }
            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off,428, 160, 32, "Delete selected chunk");
                o->callback(delChunkAtCB);
            }
            updateChunkSize();

            lua_getglobal(Lconf,"tabConfig");
            lua_pushinteger(Lconf,chunkEditor);
            runLuaFunc(Lconf,1,0);
            tabsMain[chunkEditor]->end();
        }
        {   tabsMain.emplace_back(new Fl_Group(rx,ry,rw,rh,"Sprites"));
            palBar.addTab(3,false,true,true);
            {   Fl_Group *o = new Fl_Group(tile_place_buttons_x_off+616, 44, 88, 96);
                {
                    palType[9] = new Fl_Round_Button(tile_place_buttons_x_off+616, 44, 64, 24, "Free");
                    palType[9]->type(FL_RADIO_BUTTON);
                    palType[9]->set();
                    palType[9]->callback((Fl_Callback*) setPalType,(void *)0);
                    palType[9]->tooltip(freeDes);
                    palType[10] = new Fl_Round_Button(tile_place_buttons_x_off+616, 68, 72, 24, "Locked");
                    palType[10]->type(FL_RADIO_BUTTON);
                    palType[10]->callback((Fl_Callback*) setPalType,(void *)1);
                    palType[10]->tooltip(lockedDes);
                    palType[11] = new Fl_Round_Button(tile_place_buttons_x_off+616, 92, 88, 24, "Reserved");
                    palType[11]->type(FL_RADIO_BUTTON);
                    palType[11]->callback((Fl_Callback*) setPalType,(void *)2);
                    palType[11]->tooltip(reservedDes);
                    o->end();
                }
            }

            spritegrouptxt = new Fl_Input(tile_place_buttons_x_off+616,128,168,24,"Group name");
            spritegrouptxt->align(FL_ALIGN_TOP);
            spritegrouptxt->value(spriteDefName);
            spritegrouptxt->callback(assignSpritegroupnameCB);

            spritemetatxt = new Fl_Input(tile_place_buttons_x_off+616,168,168,24,"Meta name");
            spritemetatxt->value(spritesName);
            spritemetatxt->callback(assignSpritemetaNameCB);
            spritemetatxt->align(FL_ALIGN_TOP);

            spriteglobaltxt = new Fl_Input(tile_place_buttons_x_off+616,208,168,24,"All meta name");
            spriteglobaltxt->value(defMDesc);
            spriteglobaltxt->callback(assignSpriteAllMetanameCB);
            spriteglobaltxt->align(FL_ALIGN_TOP);


            metaspritesel=new Fl_Hor_Value_Slider(tile_place_buttons_x_off+616,244,168,24,"Meta group select:");
            metaspritesel->step(1);
            metaspritesel->maximum(0);
            metaspritesel->align(FL_ALIGN_TOP);
            metaspritesel->callback(selspriteMeta);
            metaspritesel->labelsize(12);


            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off+616, 274, 96, 28, "Append meta");
                o->callback(appendSpriteCB,(void*)(intptr_t)2);
            }

            spriteselgroup=new Fl_Hor_Value_Slider(tile_place_buttons_x_off,184,168,22,"Sprite group select:");
            spriteselgroup->step(1);
            spriteselgroup->maximum(0);
            spriteselgroup->align(FL_ALIGN_TOP);
            spriteselgroup->callback(selspriteGroup);
            spriteselgroup->labelsize(12);

            spritesel=new Fl_Hor_Value_Slider(tile_place_buttons_x_off,220,168,22,"Sprite select:");
            spritesel->step(1);
            spritesel->maximum(0);
            spritesel->align(FL_ALIGN_TOP);
            spritesel->callback(selSpriteCB);
            spritesel->labelsize(12);

            spritest=new Fl_Hor_Value_Slider(tile_place_buttons_x_off,256,168,22,"Start tile:");
            spritest->step(1);
            spritest->maximum(0);
            spritest->align(FL_ALIGN_TOP);
            spritest->callback(setvalueSpriteCB,0);
            spritest->labelsize(12);

            spriteslat=new Fl_Hor_Value_Slider(tile_place_buttons_x_off,292,168,22,"Mapping tile");
            spriteslat->step(1);
            spriteslat->maximum(0);
            spriteslat->align(FL_ALIGN_TOP);
            spriteslat->callback(setvalueSpriteCB,(void*)4);
            spriteslat->labelsize(12);

            spritesize[0]=new Fl_Hor_Value_Slider(tile_place_buttons_x_off+40,316,128,22,"Width");
            spritesize[0]->step(1);
            spritesize[0]->value(1);
            spritesize[0]->minimum(1);
            spritesize[0]->maximum(4);
            spritesize[0]->align(FL_ALIGN_LEFT);
            spritesize[0]->callback(setvalueSpriteCB,(void*)1);
            spritesize[0]->labelsize(12);

            spritesize[1]=new Fl_Hor_Value_Slider(tile_place_buttons_x_off+40,340,128,22,"Height");
            spritesize[1]->step(1);
            spritesize[1]->value(1);
            spritesize[1]->minimum(1);
            spritesize[1]->maximum(4);
            spritesize[1]->align(FL_ALIGN_LEFT);
            spritesize[1]->callback(setvalueSpriteCB,(void*)2);
            spritesize[1]->labelsize(12);

            spritepalrow=new Fl_Hor_Value_Slider(tile_place_buttons_x_off,376,168,22,"Palette row:");
            spritepalrow->step(1);
            spritepalrow->maximum(3);
            spritepalrow->align(FL_ALIGN_TOP);
            spritepalrow->callback(setvalueSpriteCB,(void*)3);
            spritepalrow->labelsize(12);

            spritezoom=new Fl_Hor_Value_Slider(tile_place_buttons_x_off+38,400,130,22,"Zoom");
            spritezoom->step(1);
            spritezoom->minimum(1);
            spritezoom->value(16);
            spritezoom->maximum(16);
            spritezoom->align(FL_ALIGN_LEFT);
            spritezoom->callback(redrawOnlyCB);
            spritezoom->labelsize(12);

            spritesoff[0] = new Fl_Int_Input(tile_place_buttons_x_off+62,424,106,24,"Offset X:");
            spritesoff[0]->when(FL_WHEN_ENTER_KEY);
            spritesoff[0]->value("0");
            spritesoff[0]->align(FL_ALIGN_LEFT);
            spritesoff[0]->callback(setoffspriteCB,0);

            spritesoff[1] = new Fl_Int_Input(tile_place_buttons_x_off+62,448,106,24,"Offset Y:");
            spritesoff[1]->when(FL_WHEN_ENTER_KEY);
            spritesoff[1]->value("0");
            spritesoff[1]->align(FL_ALIGN_LEFT);
            spritesoff[1]->callback(setoffspriteCB,(void*)1);

            spritehflip = new Fl_Check_Button(tile_place_buttons_x_off,470,48,20,"Hflip");
            spritehflip->callback(spriteHflipCB);
            spritevflip = new Fl_Check_Button(tile_place_buttons_x_off+52,470,48,20,"Vflip");
            spritevflip->callback(spriteVflipCB);
            spriteprio = new Fl_Check_Button(tile_place_buttons_x_off+104,470,56,20,"Priority");
            spriteprio->callback(spritePrioCB);

            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off, 492, 64, 28, "Append");
                o->callback(appendSpriteCB,0);
                o->labelsize(12);
            }
            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off+72, 492, 96, 28, "Append group");
                o->callback(appendSpriteCB,(void*)(intptr_t)1);
                o->labelsize(12);
            }
            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off, 522, 64, 28, "Delete");
                o->callback(delSpriteCB,0);
                o->labelsize(12);
            }
            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off+72, 522, 96, 28, "Delete group");
                o->callback(delSpriteCB,(void*)1);
                o->labelsize(12);
            }
            spritealign[0] = new Fl_Button(tile_place_buttons_x_off, 552, 32, 28, "Left");
            spritealign[0]->labelsize(12);
            spritealign[0]->callback(alignSpriteCB,(void*)0);

            spritealign[1] = new Fl_Button(tile_place_buttons_x_off+34, 552, 40, 28, "Right");
            spritealign[1]->labelsize(12);
            spritealign[1]->callback(alignSpriteCB,(void*)1);

            spritealign[2] = new Fl_Button(tile_place_buttons_x_off+78, 552, 28, 28, "Top");
            spritealign[2]->labelsize(12);
            spritealign[2]->callback(alignSpriteCB,(void*)2);

            spritealign[3] = new Fl_Button(tile_place_buttons_x_off+112, 552, 48, 28, "Bottom");
            spritealign[3]->labelsize(12);
            spritealign[3]->callback(alignSpriteCB,(void*)3);

            {
                Fl_Group *o = new Fl_Group(tile_place_buttons_x_off, 572, 800, 480);
                {
                    Fl_Round_Button*m = new Fl_Round_Button(tile_place_buttons_x_off, 572, 96, 32, "Top corner");
                    m->type(FL_RADIO_BUTTON);
                    m->callback(setDrawSpriteCB,(void *)0);
                    m->set();
                } // Fl_Round_Button* o
                {
                    Fl_Round_Button*m = new Fl_Round_Button(tile_place_buttons_x_off+96, 572, 64, 32, "Center");
                    m->type(FL_RADIO_BUTTON);
                    m->callback(setDrawSpriteCB,(void *)1);
                } // Fl_Round_Button* o
                o->end();
            } // End of buttons

            lua_getglobal(Lconf,"tabConfig");
            lua_pushinteger(Lconf,spriteEditor);
            runLuaFunc(Lconf,1,0);
            tabsMain[spriteEditor]->end();
        }
        {   tabsMain.emplace_back(new Fl_Group(rx,ry,rw,rh,"Level editor"));
            lua_getglobal(Lconf,"tabConfig");
            lua_pushinteger(Lconf,levelEditor);
            runLuaFunc(Lconf,1,0);
            tabsMain[levelEditor]->end();
        }
        {   tabsMain.emplace_back(new Fl_Group(rx,ry,rw,rh,"Settings/projects"));
            projectSelect=new Fl_Hor_Value_Slider(112,56,128,24,"Current project");
            projectSelect->minimum(0);
            projectSelect->maximum(0);
            projectSelect->step(1);
            projectSelect->value(0);
            projectSelect->align(FL_ALIGN_LEFT);
            projectSelect->callback(switchProjectCB);
            {   Fl_Button *o = new Fl_Button(260, 52, 152, 32, "Append blank project");
                o->callback(appendProjectCB);
            }
            {   Fl_Button *o = new Fl_Button(428, 52, 168, 32, "Delete selected project");
                o->callback(deleteProjectCB);
            }
            //IMPORTANT if adding a new tab remember to update these
            sharePrj[0]=new Fl_Check_Button(8,112,112,16,"Share palette");
            sharePrj[0]->callback(shareProjectCB,(void*)pjHavePal);
            sharePrj[1]=new Fl_Check_Button(120,112,96,16,"Share tiles");
            sharePrj[1]->callback(shareProjectCB,(void*)pjHaveTiles);
            sharePrj[2]=new Fl_Check_Button(216,112,120,16,"Share tile map");
            sharePrj[2]->callback(shareProjectCB,(void*)pjHaveMap);
            sharePrj[3]=new Fl_Check_Button(336,112,120,16,"Share chunks");
            sharePrj[3]->callback(shareProjectCB,(void*)pjHaveChunks);
            sharePrj[4]=new Fl_Check_Button(456,112,120,16,"Share sprites");
            sharePrj[4]->callback(shareProjectCB,(void*)pjHaveSprites);
            sharePrj[5]=new Fl_Check_Button(576,112,120,16,"Share level");
            sharePrj[5]->callback(shareProjectCB,(void*)pjHaveLevel);

            havePrj[0]=new Fl_Check_Button(8,88,112,16,"Have palette");
            havePrj[0]->callback(haveCB,(void*)pjHavePal);
            havePrj[1]=new Fl_Check_Button(120,88,96,16,"Have tiles");
            havePrj[1]->callback(haveCB,(void*)pjHaveTiles);
            havePrj[2]=new Fl_Check_Button(232,88,120,16,"Have tile map");
            havePrj[2]->callback(haveCB,(void*)pjHaveMap);
            havePrj[3]=new Fl_Check_Button(344,88,120,16,"Have chunks");
            havePrj[3]->callback(haveCB,(void*)pjHaveChunks);
            havePrj[4]=new Fl_Check_Button(456,88,120,16,"Have sprites");
            havePrj[4]->callback(haveCB,(void*)pjHaveSprites);
            havePrj[5]=new Fl_Check_Button(568,88,120,16,"Have level");
            havePrj[5]->callback(haveCB,(void*)pjHaveLevel);

            shareWith[0]=new Fl_Hor_Value_Slider(8,142,128,24,"Share palette with:");
            shareWith[0]->callback(switchShareCB,(void*)pjHavePal);
            shareWith[1]=new Fl_Hor_Value_Slider(136,142,128,24,"Share tiles with:");
            shareWith[1]->callback(switchShareCB,(void*)pjHaveTiles);
            shareWith[2]=new Fl_Hor_Value_Slider(264,142,128,24,"Share tile map with:");
            shareWith[2]->callback(switchShareCB,(void*)pjHaveMap);
            shareWith[3]=new Fl_Hor_Value_Slider(400,142,128,24,"Share chunks with:");
            shareWith[3]->callback(switchShareCB,(void*)pjHaveChunks);
            shareWith[4]=new Fl_Hor_Value_Slider(536,142,128,24,"Share sprites with:");
            shareWith[4]->callback(switchShareCB,(void*)pjHaveSprites);
            shareWith[5]=new Fl_Hor_Value_Slider(672,142,128,24,"Share level with:");
            shareWith[5]->callback(switchShareCB,(void*)pjHaveLevel);
            for(unsigned x=0; x<shareAmtPj; ++x) {
                havePrj[x]->value(1);
                shareWith[x]->minimum(0);
                shareWith[x]->maximum(0);
                shareWith[x]->step(1);
                shareWith[x]->value(0);
                shareWith[x]->align(FL_ALIGN_TOP);
            }


            TxtBufProject = new Fl_Text_Buffer;
            TxtEditProject = new Fl_Text_Editor(8, 184, 640, 370,"Description/Notes");
            TxtEditProject->buffer(TxtBufProject);
            TxtEditProject->textfont(FL_TIMES);
            TxtBufProject->text(currentProject->Name.c_str());
            lua_getglobal(Lconf,"tabConfig");
            lua_pushinteger(Lconf,settingsTab);
            runLuaFunc(Lconf,1,0);
            tabsMain[settingsTab]->end();
        }
        {   tabsMain.emplace_back(new Fl_Group(rx,ry,rw,rh,"Lua scripting"));
            luaScriptSel=new Fl_Choice(tile_place_buttons_x_off,default_palette_bar_offset_y+8,112,24);
            luaScriptSel->label("Script selection");
            luaScriptSel->align(FL_ALIGN_TOP);
            luaScriptSel->callback(switchCurLuaScript);
            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off+120, default_palette_bar_offset_y,112, 32, "Append script");
                o->callback(appendLuaScript);
            }
            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off+240, default_palette_bar_offset_y,144,32, "Delete selected script");
                o->callback(deleteLuaScript);
            }
            {   Fl_Button *o = new Fl_Button(tile_place_buttons_x_off+392, default_palette_bar_offset_y,48,32, "Run");
                o->callback(runCurLuaScript);
            }
            luaScriptName = new Fl_Input(tile_place_buttons_x_off+448+8,default_palette_bar_offset_y+8,328,24,"Script name");
            luaScriptName->callback(setNameLuaScript);
            luaScriptName->align(FL_ALIGN_TOP);
            luaBufProject = new Fl_Text_Buffer;
            luaEditProject = new Fl_Text_Editor(tile_place_buttons_x_off,default_palette_bar_offset_y+48, 784, 456,"Currently selected Lua script");
            luaEditProject->buffer(luaBufProject);
            luaEditProject->textfont(FL_COURIER);
            luaEditProject->hide();
            lua_getglobal(Lconf,"tabConfig");
            lua_pushinteger(Lconf,luaTab);
            runLuaFunc(Lconf,1,0);
            tabsMain[luaTab]->end();
        }
    }
}
Example #15
0
File: routing.c Project: aishp/rpl
int diorecv_callback(lua_State *L)
{
	lua_pushlightfunction(L, libmsgpack_mp_unpack);
	lua_pushvalue(L, 1);
	lua_call(L, 1, 1);
	int tab_index=lua_gettop(L); //DIO received
	char *srcip = (char *)lua_tostring(L, 2);
	
	//stop DIS multicast
	lua_getglobal(L, "dismflag"); //flag that checks if dis is still being multicast
	if(lua_tonumber(L, -1)==1)
	{
		lua_pushlightfunction(L, libstorm_net_close);
		lua_getglobal(L, "dismcast_sock");
		lua_call(L, 1, 0);
		lua_pushnumber(L, 0);
		lua_setglobal(L, "dismflag");
	}
	
	lua_getglobal(L, "DIO");
	int self_dio= lua_gettop(L); 
	
	
	lua_pushstring(L, "rank");
	lua_gettable(L, self_dio);
	int s_rank = lua_tonumber(L, -1);
	
	if(lua_tonumber(L, -1)>1) // not a root node
	{
		
		lua_pushstring(L, "rank");
		lua_gettable(L, tab_index);
		int p_rank = lua_tonumber(L, -1);
		
		if(p_rank < s_rank)
		{
			//add to parent list
			lua_getglobal(L, "parent_table");
			lua_pushstring(L, srcip);
			lua_pushnumber(L, p_rank);
			lua_settable(L, -3);
			lua_setglobal(L, "parent_table");
		}
	
		if((s_rank == 10000) || (s_rank > (p_rank+1)))
		{
			//set preferred parent as incoming DIO, which is on top of the stack
			lua_pushstring(L, srcip);
			lua_setglobal(L, "PrefParent");
			lua_pop(L, 1);
			
			//Update self dio with new rank, gf, dodag_id, etx and version (from parent)
			lua_pushlightfunction(L, dio_init);
			lua_pushstring(L, "rank");
			lua_pushnumber(L, lua_tonumber(L, -1)+1);//push new rank
			lua_pushnumber(L, 1);//GF=1
			lua_pushstring(L, "dodag_id");
			lua_gettable(L, tab_index);//same dodag_id as parent
			lua_pushstring(L, "etx");
			lua_gettable(L, tab_index);
			int etx=lua_tonumber(L, -1);
			lua_pop(L, 1);
			lua_pushnumber(L,etx+1);//etx of parent+1 (for now,later add another measure for calculating etx)
			lua_pushstring(L, "version");
			lua_gettable(L, tab_index);//same dodag_version as parent
			lua_call(L, 5, 0);
	
			//inconsistent state reached, reset everything and start trickle timer again
			//**STOP THE OLD INSTANCE OF TRICKLE TIMER**
			lua_getglobal(L, "TRICKLE_INSTANCE");
			lua_pushnumber(L, lua_tonumber(L, -1)+1);
			lua_setglobal(L, "TRICKLE_INSTANCE");
			lua_pushlightfunction(L, trickle_timer);
			lua_call(L, 0, 0);
		}
	
		else
		{
			//consistent state, increment C(trickle timer counter)
			lua_getglobal(L, "C");
			lua_pushnumber(L, lua_tonumber(L, -1)+1);
			lua_setglobal(L, "C");
		}	
	}
	
	return 0;
}
Example #16
0
void evalGenericCommand(redisClient *c, int evalsha) {
    lua_State *lua = server.lua;
    char funcname[43];
    long long numkeys;
    int delhook = 0;

    /* We want the same PRNG sequence at every call so that our PRNG is
     * not affected by external state. */
    redisSrand48(0);

    /* We set this flag to zero to remember that so far no random command
     * was called. This way we can allow the user to call commands like
     * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command
     * is called (otherwise the replication and AOF would end with non
     * deterministic sequences).
     *
     * Thanks to this flag we'll raise an error every time a write command
     * is called after a random command was used. */
    server.lua_random_dirty = 0;
    server.lua_write_dirty = 0;

    /* Get the number of arguments that are keys */
    if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK)
        return;
    if (numkeys > (c->argc - 3)) {
        addReplyError(c,"Number of keys can't be greater than number of args");
        return;
    }

    /* We obtain the script SHA1, then check if this function is already
     * defined into the Lua state */
    funcname[0] = 'f';
    funcname[1] = '_';
    if (!evalsha) {
        /* Hash the code if this is an EVAL call */
        sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
    } else {
        /* We already have the SHA if it is a EVALSHA */
        int j;
        char *sha = c->argv[1]->ptr;

        for (j = 0; j < 40; j++)
            funcname[j+2] = tolower(sha[j]);
        funcname[42] = '\0';
    }

    /* Try to lookup the Lua function */
    lua_getglobal(lua, funcname);
    if (lua_isnil(lua,1)) {
        lua_pop(lua,1); /* remove the nil from the stack */
        /* Function not defined... let's define it if we have the
         * body of the funciton. If this is an EVALSHA call we can just
         * return an error. */
        if (evalsha) {
            addReply(c, shared.noscripterr);
            return;
        }
        if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return;
        /* Now the following is guaranteed to return non nil */
        lua_getglobal(lua, funcname);
        redisAssert(!lua_isnil(lua,1));
    }

    /* Populate the argv and keys table accordingly to the arguments that
     * EVAL received. */
    luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys);
    luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys);

    /* Select the right DB in the context of the Lua client */
    selectDb(server.lua_client,c->db->id);
    
    /* Set an hook in order to be able to stop the script execution if it
     * is running for too much time.
     * We set the hook only if the time limit is enabled as the hook will
     * make the Lua script execution slower. */
    server.lua_caller = c;
    server.lua_time_start = ustime()/1000;
    server.lua_kill = 0;
    if (server.lua_time_limit > 0 && server.masterhost == NULL) {
        lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
        delhook = 1;
    }

    /* At this point whatever this script was never seen before or if it was
     * already defined, we can call it. We have zero arguments and expect
     * a single return value. */
    if (lua_pcall(lua,0,1,0)) {
        if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
        if (server.lua_timedout) {
            server.lua_timedout = 0;
            /* Restore the readable handler that was unregistered when the
             * script timeout was detected. */
            aeCreateFileEvent(server.el,c->fd,AE_READABLE,
                              readQueryFromClient,c);
        }
        server.lua_caller = NULL;
        selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
        addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
            funcname, lua_tostring(lua,-1));
        lua_pop(lua,1);
        lua_gc(lua,LUA_GCCOLLECT,0);
        return;
    }
    if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
    server.lua_timedout = 0;
    server.lua_caller = NULL;
    selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
    luaReplyToRedisReply(c,lua);
    lua_gc(lua,LUA_GCSTEP,1);

    /* If we have slaves attached we want to replicate this command as
     * EVAL instead of EVALSHA. We do this also in the AOF as currently there
     * is no easy way to propagate a command in a different way in the AOF
     * and in the replication link.
     *
     * IMPROVEMENT POSSIBLE:
     * 1) Replicate this command as EVALSHA in the AOF.
     * 2) Remember what slave already received a given script, and replicate
     *    the EVALSHA against this slaves when possible.
     */
    if (evalsha) {
        robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);

        redisAssertWithInfo(c,NULL,script != NULL);
        rewriteClientCommandArgument(c,0,
            resetRefCount(createStringObject("EVAL",4)));
        rewriteClientCommandArgument(c,1,script);
    }
}
Example #17
0
void modLib_start(lua_State *L, const char *name) {
  lua_getglobal(L, name);
}
Example #18
0
ShaderBinder::ShaderBinder(lua_State* L)
{
	Binder binder(L);

	static const luaL_Reg functionList[] = {
	        {"setConstant", setConstant},
	        {"isValid", isValid},
	    	{"getEngineVersion",getEngineVersion},
	    	{"getShaderLanguage",getShaderLanguage},
			{"enableVBO",enableVBO},
			{"getProperties",getProperties},
        {NULL, NULL},
	};

	binder.createClass("Shader", NULL, create, destruct, functionList);

	lua_getglobal(L, "Shader");

	lua_pushinteger(L, ShaderProgram::CINT);
	lua_setfield(L, -2, "CINT");
	lua_pushinteger(L, ShaderProgram::CFLOAT);
	lua_setfield(L, -2, "CFLOAT");
	lua_pushinteger(L, ShaderProgram::CFLOAT2);
	lua_setfield(L, -2, "CFLOAT2");
	lua_pushinteger(L, ShaderProgram::CFLOAT3);
	lua_setfield(L, -2, "CFLOAT3");
	lua_pushinteger(L, ShaderProgram::CFLOAT4);
	lua_setfield(L, -2, "CFLOAT4");
	lua_pushinteger(L, ShaderProgram::CTEXTURE);
	lua_setfield(L, -2, "CTEXTURE");
	lua_pushinteger(L, ShaderProgram::CMATRIX);
	lua_setfield(L, -2, "CMATRIX");

	lua_pushinteger(L, ShaderProgram::DBYTE);
	lua_setfield(L, -2, "DBYTE");
	lua_pushinteger(L, ShaderProgram::DUBYTE);
	lua_setfield(L, -2, "DUBYTE");
	lua_pushinteger(L, ShaderProgram::DSHORT);
	lua_setfield(L, -2, "DSHORT");
	lua_pushinteger(L, ShaderProgram::DUSHORT);
	lua_setfield(L, -2, "DUSHORT");
	lua_pushinteger(L, ShaderProgram::DINT);
	lua_setfield(L, -2, "DINT");
	lua_pushinteger(L, ShaderProgram::DFLOAT);
	lua_setfield(L, -2, "DFLOAT");

	lua_pushinteger(L, ShaderProgram::SysConst_None);
	lua_setfield(L, -2, "SYS_NONE");
	lua_pushinteger(L, ShaderProgram::SysConst_WorldViewProjectionMatrix);
	lua_setfield(L, -2, "SYS_WVP");
	lua_pushinteger(L, ShaderProgram::SysConst_Color);
	lua_setfield(L, -2, "SYS_COLOR");
	lua_pushinteger(L, ShaderProgram::SysConst_WorldMatrix);
	lua_setfield(L, -2, "SYS_WORLD");
	lua_pushinteger(L, ShaderProgram::SysConst_WorldInverseTransposeMatrix);
	lua_setfield(L, -2, "SYS_WIT");
	lua_pushinteger(L, ShaderProgram::SysConst_WorldInverseTransposeMatrix3);
	lua_setfield(L, -2, "SYS_WIT3");
	lua_pushinteger(L, ShaderProgram::SysConst_TextureInfo);
	lua_setfield(L, -2, "SYS_TEXTUREINFO");
	lua_pushinteger(L, ShaderProgram::SysConst_ParticleSize);
	lua_setfield(L, -2, "SYS_PARTICLESIZE");
	lua_pushinteger(L, ShaderProgram::SysConst_Timer);
	lua_setfield(L, -2, "SYS_TIMER");

	lua_pushinteger(L, ShaderProgram::Flag_None);
	lua_setfield(L, -2, "FLAG_NONE");
	lua_pushinteger(L, ShaderProgram::Flag_NoDefaultHeader);
	lua_setfield(L, -2, "FLAG_NO_DEFAULT_HEADER");
	lua_pushinteger(L, ShaderProgram::Flag_FromCode);
	lua_setfield(L, -2, "FLAG_FROM_CODE");

	lua_pop(L, 1);

}
Example #19
0
void sinsp_chisel::set_args(vector<pair<string, string>> args)
{
#ifdef HAS_LUA_CHISELS
	uint32_t j;
	uint32_t n_required_args = get_n_required_args();
	uint32_t n_optional_args = get_n_optional_args();

	ASSERT(m_ls);

	//
	// Validate the arguments
	//
	if(args.size() < n_required_args)
	{
		throw sinsp_exception("wrong number of parameters for chisel " + m_filename +
			", " + to_string((long long int)n_required_args) + " required, " + 
			to_string((long long int)args.size()) + " given");
	}
	else if(args.size() > n_optional_args + n_required_args)
	{
		throw sinsp_exception("too many parameters for chisel " + m_filename +
			", " + to_string((long long int)(n_required_args)) + " required, " +
			to_string((long long int)(n_optional_args)) + " optional, " +
			to_string((long long int)args.size()) + " given");
	}

	//
	// Push the arguments
	//
	for(j = 0; j < args.size(); j++)
	{
		lua_getglobal(m_ls, "on_set_arg");
		if(!lua_isfunction(m_ls, -1))
		{
			lua_pop(m_ls, 1);
			throw sinsp_exception("chisel " + m_filename + " misses a set_arg() function.");
		}

		lua_pushstring(m_ls, args[j].first.c_str()); 
		lua_pushstring(m_ls, args[j].second.c_str());

		//
		// call get_info()
		//
		if(lua_pcall(m_ls, 2, 1, 0) != 0) 
		{
			throw sinsp_exception(m_filename + " chisel error: " + lua_tostring(m_ls, -1));
		}

		if(!lua_isboolean(m_ls, -1)) 
		{
			throw sinsp_exception(m_filename + " chisel error: wrong set_arg() return value.");
		}

		int sares = lua_toboolean(m_ls, -1);

		if(!sares)
		{
			throw sinsp_exception("set_arg() for chisel " + m_filename + " failed.");
		}

		lua_pop(m_ls, 1);
	}
#endif
}
Example #20
0
LUAMODULE_API int luaopen_ex_core(lua_State *L)
{
  const char *name = lua_tostring(L, 1);
  int ex;
  const luaL_reg ex_iolib[] = {
    {"pipe",       ex_pipe},
#define ex_iofile_methods (ex_iolib + 1)
    {"lock",       ex_lock},
    {"unlock",     ex_lock},
    {0,0} };
  const luaL_reg ex_oslib[] = {
    /* environment */
    {"getenv",     ex_getenv},
    {"setenv",     ex_setenv},
    {"environ",    ex_environ},
    /* file system */
    {"access",     ex_access},
    {"getcwd",     ex_getcwd},
    {"chdir",      ex_chdir},
    {"chmod",      ex_chmod},
    {"mkdir",      ex_mkdir},
    {"remove",     ex_remove},
    {"dir",        ex_dir},
    {"dirent",     ex_dirent},
    {"copyfile",   ex_copyfile},
    {"movefile",   ex_movefile},
    {"touch",   ex_touch},
    {"stdin_binary", ex_stdin_binary},
    {"stdout_binary", ex_stdout_binary},
    /* process control */
    {"sleep",      ex_sleep},
    {"spawn",      ex_spawn},
    {0,0} };
  const luaL_reg ex_diriter_methods[] = {
    {"__gc",       diriter_close},
    {0,0} };
  const luaL_reg ex_process_methods[] = {
    {"__tostring", process_tostring},
#define ex_process_functions (ex_process_methods + 1)
    {"wait",       process_wait},
    {"__gc",       process_close},
    {0,0} };
  /* diriter metatable */
  luaL_newmetatable(L, DIR_HANDLE);           /* . D */
  luaL_register(L, 0, ex_diriter_methods);    /* . D */
  /* proc metatable */
  luaL_newmetatable(L, PROCESS_HANDLE);       /* . P */
  luaL_register(L, 0, ex_process_methods);    /* . P */
  lua_pushvalue(L, -1);                       /* . P P */
  lua_setfield(L, -2, "__index");             /* . P */
  /* make all functions available via ex. namespace */
  luaL_register(L, name, ex_oslib);           /* . P ex */
  luaL_register(L, 0, ex_iolib);
  copyfields(L, ex_process_functions, -2, -1);
  ex = lua_gettop(L);
  /* extend the os table */
  lua_getglobal(L, "os");                     /* . os */
  if (lua_isnil(L, -1)) return luaL_error(L, "os not loaded");
  copyfields(L, ex_oslib, ex, -1);
  luaopen_os_path(L);
  /* extend the io table */
  lua_getglobal(L, "io");                     /* . io */
  if (lua_isnil(L, -1)) return luaL_error(L, "io not loaded");
  copyfields(L, ex_iolib, ex, -1);
//  copyfields(L, ex_iolib, ex, -1);
  lua_getfield(L, ex, "pipe");                /* . io ex_pipe */
  newfenv(L, pipe_close);  /* create environment for 'popen' */
  lua_setfenv(L, -2);  /* set fenv for 'popen' */
  lua_pop(L, 1);  /* pop 'popen' */
  /* extend the io.file metatable */
  luaL_getmetatable(L, LUA_FILEHANDLE);       /* . F */
  if (lua_isnil(L, -1)) return luaL_error(L, "can't find FILE* metatable");
  copyfields(L, ex_iofile_methods, ex, -1);
  luaopen_windows_hkey(L);
  return 1;
}
Example #21
0
bool sinsp_chisel::run(sinsp_evt* evt)
{
#ifdef HAS_LUA_CHISELS
	string line;

	ASSERT(m_ls);

	//
	// Make the event available to the API
	//
	lua_pushlightuserdata(m_ls, evt);
	lua_setglobal(m_ls, "sievt");

	//
	// If this is the first event, put the event pointer on the stack.
	// We assume that the event pointer will never change.
	//
	if(m_lua_is_first_evt)
	{
		first_event_inits(evt);
	}

	//
	// If there is a timeout callback, see if it's time to call it
	//
	do_timeout(evt);

	//
	// If there is a filter, run it
	//
	if(m_lua_cinfo->m_filter != NULL)
	{
		if(!m_lua_cinfo->m_filter->run(evt))
		{
			return false;
		}
	}

	//
	// If the script has the on_event callback, call it
	//
	if(m_lua_has_handle_evt)
	{
		lua_getglobal(m_ls, "on_event");
			
		if(lua_pcall(m_ls, 0, 1, 0) != 0) 
		{
			throw sinsp_exception(m_filename + " chisel error: " + lua_tostring(m_ls, -1));
		}
	
		int oeres = lua_toboolean(m_ls, -1);
		lua_pop(m_ls, 1);

		if(m_lua_cinfo->m_end_capture == true)
		{
			throw sinsp_capture_interrupt_exception();
		}

		if(oeres == false)
		{
			return false;
		}
	}

	//
	// If the script has a formatter, run it
	//
	if(m_lua_cinfo->m_formatter != NULL)
	{
		if(m_lua_cinfo->m_formatter->tostring(evt, &line))
		{
			cout << line << endl;
		}
	}

	return true;
#endif
}
Example #22
0
File: slua.c Project: stoneby/slua
static void getmetatable(lua_State *L, const char* key) {
	char ns[256];
	snprintf(ns, 256, "UnityEngine.%s.Instance", key);

	lua_getglobal(L, ns);
}
Example #23
0
// Initializes a lua chisel
bool sinsp_chisel::init_lua_chisel(chisel_desc &cd, string const &fpath)
{
	lua_State* ls = lua_open();
	if(ls == NULL)
	{
		return false;
	}

	luaL_openlibs(ls);

	//
	// Load our own lua libs
	//
	luaL_openlib(ls, "sysdig", ll_sysdig, 0);
	luaL_openlib(ls, "chisel", ll_chisel, 0);
	luaL_openlib(ls, "evt", ll_evt, 0);

	//
	// Add our chisel paths to package.path
	//
	for(vector<chiseldir_info>::const_iterator it = g_chisel_dirs->begin();
		it != g_chisel_dirs->end(); ++it)
	{
		string path(it->m_dir);
		path += "?.lua";
		add_lua_package_path(ls, path.c_str());
	}

	//
	// Load the script
	//
	if(luaL_loadfile(ls, fpath.c_str()) || lua_pcall(ls, 0, 0, 0))
	{
		goto failure;
	}

	//
	// Extract the description
	//
	lua_getglobal(ls, "description");
	if(!lua_isstring(ls, -1))
	{
		return parse_view_info(ls, &cd);
	}
	cd.m_description = lua_tostring(ls, -1);

	//
	// Extract the short description
	//
	lua_getglobal(ls, "short_description");
	if(!lua_isstring(ls, -1))
	{
		goto failure;
	}
	cd.m_shortdesc = lua_tostring(ls, -1);

	//
	// Extract the category
	//
	cd.m_category = "";
	lua_getglobal(ls, "category");
	if(lua_isstring(ls, -1))
	{
		cd.m_category = lua_tostring(ls, -1);
	}

	//
	// Extract the hidden flag and skip the chisel if it's set
	//
	lua_getglobal(ls, "hidden");
	if(lua_isboolean(ls, -1))
	{
		int sares = lua_toboolean(ls, -1);
		if(sares)
		{
			goto failure;
		}
	}

	//
	// Extract the args
	//
	lua_getglobal(ls, "args");
	if(lua_isnoneornil(ls, -1))
	{
		goto failure;
	}

	try
	{
		parse_lua_chisel_args(ls, &cd);
	}
	catch(...)
	{
		goto failure;
	}

	return true;

failure:
	lua_close(ls);
	return false;
}
Example #24
0
/* Initialize the scripting environment.
 *
 * 初始化脚本环境。
 *
 * It is possible to call this function to reset the scripting environment
 * assuming that we call scriptingRelease() before.
 *
 * 这个函数也可以在 scriptingRelease() 执行之后使用,用于对脚本环境进行重置。
 *
 * See scriptingReset() for more information.
 */
void scriptingInit(void)
{
    // 创建一个新的 lua 环境
    lua_State *lua = lua_open();

    // 载入内置函数库
    luaLoadLibraries(lua);

    // 屏蔽所有不想暴露给脚本环境的函数(目前只有 loadfile)
    luaRemoveUnsupportedFunctions(lua);

    /* Initialize a dictionary we use to map SHAs to scripts.
     * 创建一个字典,用于将 SHA 校验码映射到脚本
     * This is useful for replication, as we need to replicate EVALSHA
     * as EVAL, so we need to remember the associated script.
     * 因为 Redis 目前复制脚本的方法是将 EVALSHA 转换成 EVAL 来进行的,
     * 所以程序需要保存和 SHA 校验值相对应的脚本。
     */
    server.lua_scripts = dictCreate(&shaScriptObjectDictType,NULL);

    /* Register the redis commands table and fields */
    // 创建 table ,并以给定名称将 C 函数注册到表格上
    lua_newtable(lua);

    /* 注册 redis.call */
    lua_pushstring(lua,"call");
    lua_pushcfunction(lua,luaRedisCallCommand);
    lua_settable(lua,-3);

    /* 注册 redis.pcall */
    lua_pushstring(lua,"pcall");
    lua_pushcfunction(lua,luaRedisPCallCommand);
    lua_settable(lua,-3);

    /* 注册 redis.log 和 log levels. */
    lua_pushstring(lua,"log");
    lua_pushcfunction(lua,luaLogCommand);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_DEBUG");
    lua_pushnumber(lua,REDIS_DEBUG);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_VERBOSE");
    lua_pushnumber(lua,REDIS_VERBOSE);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_NOTICE");
    lua_pushnumber(lua,REDIS_NOTICE);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_WARNING");
    lua_pushnumber(lua,REDIS_WARNING);
    lua_settable(lua,-3);

    /* 注册 redis.sha1hex */
    lua_pushstring(lua, "sha1hex");
    lua_pushcfunction(lua, luaRedisSha1hexCommand);
    lua_settable(lua, -3);

    /* 注册 redis.error_reply and redis.status_reply */
    lua_pushstring(lua, "error_reply");
    lua_pushcfunction(lua, luaRedisErrorReplyCommand);
    lua_settable(lua, -3);
    lua_pushstring(lua, "status_reply");
    lua_pushcfunction(lua, luaRedisStatusReplyCommand);
    lua_settable(lua, -3);

    /* Finally set the table as 'redis' global var. */
    // 将 table 设置为 redis 全局变量
    lua_setglobal(lua,"redis");

    /* Replace math.random and math.randomseed with our implementations. */
    // 将 math.random 和 math.randomseed 设置为 Redis 实现
    // 用于生成确定性的随机数
    // (对于同一个 seed ,生成的随机序列总是相同)
    lua_getglobal(lua,"math");

    lua_pushstring(lua,"random");
    lua_pushcfunction(lua,redis_math_random);
    lua_settable(lua,-3);

    lua_pushstring(lua,"randomseed");
    lua_pushcfunction(lua,redis_math_randomseed);
    lua_settable(lua,-3);

    lua_setglobal(lua,"math");

    /* Add a helper funciton that we use to sort the multi bulk output of non
     * deterministic commands, when containing 'false' elements.
     * 用于对不确定性多个回复的输出进行排序
     */
    {
        char *compare_func =    "function __redis__compare_helper(a,b)\n"
                                "  if a == false then a = '' end\n"
                                "  if b == false then b = '' end\n"
                                "  return a<b\n"
                                "end\n";
        luaL_loadbuffer(lua,compare_func,strlen(compare_func),"@cmp_func_def");
        lua_pcall(lua,0,0,0);
    }

    /* Create the (non connected) client that we use to execute Redis commands
     * inside the Lua interpreter.
     * 创建一个无网络连接的伪客户端,用于执行 Lua 脚本中的命令
     * Note: there is no need to create it again when this function is called
     * by scriptingReset().
     */
    if (server.lua_client == NULL)
    {
        server.lua_client = createClient(-1);
        server.lua_client->flags |= REDIS_LUA_CLIENT;
    }

    /* Lua beginners ofter don't use "local", this is likely to introduce
     * subtle bugs in their code. To prevent problems we protect accesses
     * to global variables.
     *
     * 为了避免全局变量被意外地修改,保护全局变量。
     */
    scriptingEnableGlobalsProtection(lua);

    // 将 lua 环境赋值到服务器变量
    server.lua = lua;
}
Example #25
0
/*
** Read the options specified in the ini file.
**
*/
void CMeasureScript::ReadOptions(CConfigParser& parser, const WCHAR* section)
{
	CMeasure::ReadOptions(parser, section);

	std::wstring file = parser.ReadString(section, L"ScriptFile", L"");

	if (!file.empty())
	{
		if (m_MeterWindow)
		{
			m_MeterWindow->MakePathAbsolute(file);
		}

		if (!m_Initialized ||
			wcscmp(file.c_str(), m_ScriptFile.c_str()) != 0)
		{
			DeleteLuaScript();

			lua_State* L = LuaManager::GetState();
			m_ScriptFile = file;
			m_LuaScript = new LuaScript(m_ScriptFile.c_str());

			if (m_LuaScript->IsInitialized())
			{
				m_HasInitializeFunction = m_LuaScript->IsFunction(g_InitializeFunctionName);
				m_HasUpdateFunction = m_LuaScript->IsFunction(g_UpdateFunctionName);
				m_HasGetStringFunction = m_LuaScript->IsFunction(g_GetStringFunctionName);  // For backwards compatbility

				if (m_HasGetStringFunction)
				{
					LogWithArgs(LOG_WARNING, L"Script: Using deprecated GetStringValue() in [%s]", m_Name.c_str());
				}

				lua_rawgeti(L, LUA_GLOBALSINDEX, m_LuaScript->GetRef());

				*(CMeterWindow**)lua_newuserdata(L, sizeof(CMeterWindow*)) = m_MeterWindow;
				lua_getglobal(L, "CMeterWindow");
				lua_setmetatable(L, -2);
				lua_setfield(L, -2, "SKIN");

				*(CMeasure**)lua_newuserdata(L, sizeof(CMeasure*)) = this;
				lua_getglobal(L, "CMeasure");
				lua_setmetatable(L, -2);
				lua_setfield(L, -2, "SELF");

				// For backwards compatibility
				lua_getfield(L, -1, "PROPERTIES");
				if (lua_isnil(L, -1) == 0)
				{
					lua_pushnil(L);
					
					// Look in the table for values to read from the section
					while (lua_next(L, -2))
					{
						lua_pop(L, 1);
						const char* strKey = lua_tostring(L, -1);

						std::wstring wstrKey = ConvertToWide(strKey);
						const std::wstring& wstrValue = parser.ReadString(section, wstrKey.c_str(), L"");

						if (!wstrValue.empty())
						{
							LuaManager::PushWide(L, wstrValue.c_str());
							lua_setfield(L, -3, strKey);
						}
					}
				}

				// Pop PROPERTIES table and our table
				lua_pop(L, 2);
			}
			else
			{
				DeleteLuaScript();
			}
		}
	}
	else
	{
		LogWithArgs(LOG_ERROR, L"Script: File not valid in [%s]", m_Name.c_str());
		DeleteLuaScript();
	}
}
Example #26
0
void evalGenericCommand(redisClient *c, int evalsha)
{
    lua_State *lua = server.lua;
    char funcname[43];
    long long numkeys;
    int delhook = 0;

    /* We want the same PRNG sequence at every call so that our PRNG is
     * not affected by external state.
     *
     * 在每次执行 EVAL 时重置随机 seed ,从而保证可以生成相同的随机序列。
     */
    redisSrand48(0);

    /* We set this flag to zero to remember that so far no random command
     * was called. This way we can allow the user to call commands like
     * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command
     * is called (otherwise the replication and AOF would end with non
     * deterministic sequences).
     *
     * Thanks to this flag we'll raise an error every time a write command
     * is called after a random command was used.
     *
     * 用两个变量,对命令进行检查
     * 确保在调用随机命令之后,再调用写命令将出现错误
     */
    server.lua_random_dirty = 0;
    server.lua_write_dirty = 0;

    /* Get the number of arguments that are keys */
    // 获取输入键的数量
    if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK)
        return;
    // 对键的正确性做一个快速检查
    if (numkeys > (c->argc - 3))
    {
        addReplyError(c,"Number of keys can't be greater than number of args");
        return;
    }

    /* We obtain the script SHA1, then check if this function is already
     * defined into the Lua state */
    // 组合出函数的名字,例如 f_282297a0228f48cd3fc6a55de6316f31422f5d17
    funcname[0] = 'f';
    funcname[1] = '_';
    if (!evalsha)
    {
        /* Hash the code if this is an EVAL call */
        // 如果执行的是 EVAL 命令,那么计算脚本的 SHA1 校验和
        sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
    }
    else
    {
        // 如果执行的是 EVALSHA 命令,直接使用传入的 SHA1 值
        /* We already have the SHA if it is a EVALSHA */
        int j;
        char *sha = c->argv[1]->ptr;

        for (j = 0; j < 40; j++)
            funcname[j+2] = tolower(sha[j]);
        funcname[42] = '\0';
    }

    /* Try to lookup the Lua function */
    // 按名查找函数
    lua_getglobal(lua, funcname);
    if (lua_isnil(lua,1))
    {

        // 没找到脚本相应的脚本

        lua_pop(lua,1); /* remove the nil from the stack */
        /* Function not defined... let's define it if we have the
         * body of the funciton. If this is an EVALSHA call we can just
         * return an error. */
        if (evalsha)
        {
            // 如果执行的是 EVALSHA ,返回脚本未找到错误
            addReply(c, shared.noscripterr);
            return;
        }
        // 如果执行的是 EVAL ,那么创建并执行新函数,然后将代码添加到脚本字典中
        if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return;
        /* Now the following is guaranteed to return non nil */
        lua_getglobal(lua, funcname);
        redisAssert(!lua_isnil(lua,1));
    }

    /* Populate the argv and keys table accordingly to the arguments that
     * EVAL received. */
    // 设置 KEYS 和 ARGV 全局变量到 Lua 环境
    luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys);
    luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys);

    /* Select the right DB in the context of the Lua client */
    // 为 Lua 所属的(伪)客户端设置数据库
    selectDb(server.lua_client,c->db->id);

    /* Set an hook in order to be able to stop the script execution if it
     * is running for too much time.
     *
     * 设置一个钩子,用于在运行时间过长时停止脚本的运作。
     *
     * We set the hook only if the time limit is enabled as the hook will
     * make the Lua script execution slower.
     *
     * 只在开启了时间限制选项时使用钩子,因为它会拖慢脚本的运行速度。
     */
    // 调用客户端
    server.lua_caller = c;
    // 脚本开始时间
    server.lua_time_start = ustime()/1000;
    // 是否杀死脚本
    server.lua_kill = 0;
    // 只在开启时间限制时使用钩子
    if (server.lua_time_limit > 0 && server.masterhost == NULL)
    {
        lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
        delhook = 1;
    }

    /* At this point whatever this script was never seen before or if it was
     * already defined, we can call it. We have zero arguments and expect
     * a single return value. */
    // 执行脚本(所属的函数)
    if (lua_pcall(lua,0,1,0))
    {

        // 以下是脚本执行出错的代码。。。

        // 删除钩子
        if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */

        // 脚本执行已超时
        if (server.lua_timedout)
        {
            // 清除超时 FLAG
            server.lua_timedout = 0;
            /* Restore the readable handler that was unregistered when the
             * script timeout was detected. */
            // 将超时钩子里删除的读事件重新加上
            aeCreateFileEvent(server.el,c->fd,AE_READABLE,
                              readQueryFromClient,c);
        }

        // 清空调用者
        server.lua_caller = NULL;
        // 更新目标数据库
        selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
        addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
                            funcname, lua_tostring(lua,-1));
        // 弹出函数
        lua_pop(lua,1);
        // 执行完整的废料回首循环(full garbage-collection cycle)
        lua_gc(lua,LUA_GCCOLLECT,0);
        // 返回
        return;
    }

    // 以下是脚本执行成功时执行的代码。。。

    // 删除钩子
    if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */

    // 清空超时 FLAG
    server.lua_timedout = 0;

    // 清空调用者
    server.lua_caller = NULL;

    // 更新 DB
    selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */

    // 将 Lua 回复转换成 Redis 回复
    luaReplyToRedisReply(c,lua);

    // 执行 1 步渐进式 GC
    lua_gc(lua,LUA_GCSTEP,1);

    /* If we have slaves attached we want to replicate this command as
     * EVAL instead of EVALSHA. We do this also in the AOF as currently there
     * is no easy way to propagate a command in a different way in the AOF
     * and in the replication link.
     *
     * 如果有附属节点,那么使用 EVAL 而不是 EVALSHA 来传播脚本
     * 因为目前还没有代码可以检测脚本是否已经传送到附属节点中
     *
     * IMPROVEMENT POSSIBLE:
     * 1) Replicate this command as EVALSHA in the AOF.
     * 2) Remember what slave already received a given script, and replicate
     *    the EVALSHA against this slaves when possible.
     */
    // 如果执行的是 EVALSHA 命令
    if (evalsha)
    {
        // 取出脚本代码体(body)
        robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);

        redisAssertWithInfo(c,NULL,script != NULL);
        // 重写客户端命令为 EVAL
        rewriteClientCommandArgument(c,0,
                                     resetRefCount(createStringObject("EVAL",4)));
        rewriteClientCommandArgument(c,1,script);
    }
}
Example #27
0
static int dolibrary (lua_State *L, const char *name) {
  lua_getglobal(L, "require");
  lua_pushstring(L, name);
  return report(L, docall(L, 1, 1));
}
Example #28
0
File: routing.c Project: aishp/rpl
int check_daoack(lua_State *L)
{
	lua_pushlightfunction(L, libmsgpack_mp_unpack);
	lua_pushvalue(L, lua_upvalueindex(1));
	lua_call(L, 1, 1);
	int t_idx=lua_gettop(L);
	
	lua_pushstring(L, "dest");
	lua_gettable(L, t_idx);
	char *d_ip= (char *)lua_tostring(L, -1);
	
	lua_getglobal(L, "DAO_ACK");
	int dt_idx=lua_gettop(L);
	lua_pushstring(L, -2); //ip address of required destination
	lua_gettable(L, -2);
	
	if(isnil(L, -1)) //No dao_ack for this ip addr
	{
		lua_getglobal(L, "PFLAG");
		int pflag = lua_tonumber(L, -1);
		if(pflag > 5) //more than 5 retransmissions already occured to this parent
		{
			//Parent is dead, find new parent
			lua_getglobal(L, "parent_table");
			int p_idx=lua_gettop(L);
			
			lua_pushnil(L);
			if(lua_next(L, p_idx)==0) // no elements in the parent table
			{
				//send poisoning DIO to release all children 
				//rebroadcast DIS
				//reinitialise dio, dis, all tables
			}
			else
			{
				
				//IP Addr of next parent is at index -2
				char *p_ip = (char *)lua_tostring(L, -2);
				int p_rank = lua_tonumber(L, -1); //rank of new parent
				lua_pop(L, 1); //now Parent IP is on top of the stack (after popping rank)
				lua_setglobal(L, "PrefParent");
				
				//remove node from parent table
				lua_pushstring(L, p_ip);
				int ref = luaL_ref (L, p_idx);
				luaL_unref(L, p_idx, ref);
				
				//remove all nodes from parent table whose rank is less than new rank
				lua_pushnil(L);
				while(lua_next(L, p_idx)!=0)
				{
					if(lua_tonumber(L, -1) > p_rank)
					{
						lua_pushvalue(L, -2); // srcip (key) of next parent)
						ref = luaL_ref (L, p_idx);
						luaL_unref(L, p_idx, ref); //remove entry from table
						//lua_pop(L, 1); //if lua_unref does not pop reference from top of the stack
					}
					lua_pop(L, 1);
				}
				
				//send dis to preferred parent, wait for DIO
				lua_pushlightfunction(L, libstorm_net_sendto);
				lua_getglobal(L,"diomcast_sock");
				lua_pushlightfunction(L, libmsgpack_mp_pack);
				lua_getglobal(L, "DIS");
				lua_call(L, 1, 1);
				lua_pushstring(L, p_ip);
				lua_pushnumber(L, disrecvport);
				lua_call(L, 4, 1); 
				
				//send new DAO all the way to the root with your own information
			}
			lua_pushnumber(L, 0);
			lua_setglobal(L, "PFLAG");
			return 0;
		}
		lua_pushnumber(L, pflag + 1);
		lua_setglobal(L, "PFLAG");
		lua_pushlightfunction(L, send_dao);
		lua_pushvalue(L, 1); //push the packed prefix table onto the stack
		lua_call(L, 1, 0);
	}
	else //ACK Received, no need to call send again, remove DAO_ACK from table
	{
		lua_pushstring(L, d_ip);
		int ref = luaL_ref (L, p_idx);
		luaL_unref(L, p_idx, ref);
		
		lua_pushvalue(L, dt_idx);
		lua_setglobal(L, "DAO_ACK");
		
		lua_pushnumber(L, 0);
		lua_setglobal(L, "PFLAG"); //Parent flag, to check if prefparent is alive
	}
	return 0;
}
Example #29
0
int lua_cbacks::push_metric(lua_State *ls) 
{
	statsd_metric metric;
	metric.m_type = statsd_metric::type_t::GAUGE;

	lua_getglobal(ls, "sichisel");

	sinsp_chisel* ch = (sinsp_chisel*)lua_touserdata(ls, -1);
	lua_pop(ls, 1);

	ASSERT(ch);
	ASSERT(ch->m_lua_cinfo);

	sinsp* inspector = ch->m_inspector;

	//
	// tags
	//
	if(lua_istable(ls, 3))
	{
		lua_pushnil(ls);

		while(lua_next(ls, 3) != 0) 
		{
			string tag = lua_tostring(ls, -1);
			metric.m_tags[tag] = "";
			lua_pop(ls, 1);
		}

		lua_pop(ls, 1);
	}
	else
	{
		string err = "error in chisel " + ch->m_filename + ": third argument must be a table";
		fprintf(stderr, "%s\n", err.c_str());
		throw sinsp_exception("chisel error");
	}

	//
	// Name
	//
	if(lua_isstring(ls, 1))
	{
		metric.m_name = lua_tostring(ls, 1);
	}
	else
	{
		string err = "errord in chisel " + ch->m_filename + ": first argument must be a string";
		fprintf(stderr, "%s\n", err.c_str());
		throw sinsp_exception("chisel error");
	}

	//
	// Value
	//
	if(lua_isnumber(ls, 2))
	{
		metric.m_value = lua_tonumber(ls, 2);
	}
	else
	{
		string err = "errord in chisel " + ch->m_filename + ": second argument must be a number";
		fprintf(stderr, "%s\n", err.c_str());
		throw sinsp_exception("chisel error");
	}

	inspector->m_analyzer->add_chisel_metric(&metric);

	return 0;
}
Example #30
0
bool Settings::save()
{
	auto& actions = m_app.getActions();
	Lumix::FS::OsFile file;
	auto& allocator = m_app.getWorldEditor()->getAllocator();
	if (!file.open(SETTINGS_PATH, Lumix::FS::Mode::CREATE_AND_WRITE, allocator)) return false;

	file << "window = { x = " << m_window.x 
		<< ", y = " << m_window.y 
		<< ", w = " << m_window.w
		<< ", h = " << m_window.h << " }\n";

	file << "maximized = " << (m_is_maximized ? "true" : "false") << "\n";

	auto writeBool = [&file](const char* name, bool value) {
		file << name << " = " << (value ? "true\n" : "false\n");
	};

	writeBool("settings_opened", m_is_opened);
	writeBool("asset_browser_opened", m_is_asset_browser_opened);
	writeBool("entity_list_opened", m_is_entity_list_opened);
	writeBool("entity_template_list_opened", m_is_entity_template_list_opened);
	writeBool("log_opened", m_is_log_opened);
	writeBool("profiler_opened", m_is_profiler_opened);
	writeBool("properties_opened", m_is_properties_opened);
	writeBool("error_reporting_enabled", m_is_crash_reporting_enabled);
	file << "mouse_sensitivity_x = " << m_mouse_sensitivity_x << "\n";
	file << "mouse_sensitivity_y = " << m_mouse_sensitivity_y << "\n";
	
	saveStyle(file);

	file << "data_dir = \"";
	const char* c = m_data_dir;
	while (*c)
	{
		if (*c == '\\') file << "\\\\";
		else file << *c;
		++c;
	}
	file << "\"\n";

	file << "custom = {\n";
	lua_getglobal(m_state, "custom");
	lua_pushnil(m_state);
	bool first = true;
	while (lua_next(m_state, -2))
	{
		if (!first) file << ",\n";
		const char* name = lua_tostring(m_state, -2);
		switch (lua_type(m_state, -1))
		{
			case LUA_TBOOLEAN:
				file << name << " = " << (lua_toboolean(m_state, -1) != 0 ? "true" : "false");
				break;
			case LUA_TNUMBER:
				file << name << " = " << (int)lua_tonumber(m_state, -1);
				break;
			default:
				ASSERT(false);
				break;
		}
		lua_pop(m_state, 1);
		first = false;
	}
	lua_pop(m_state, 1);
	file << "}\n";

	file << "actions = {\n";
	for (int i = 0; i < actions.size(); ++i)
	{
		file << "\t" << actions[i]->name << " = {" 
			<< actions[i]->shortcut[0] << ", "
			<< actions[i]->shortcut[1] << ", " 
			<< actions[i]->shortcut[2] << "},\n";
	}
	file << "}\n";

	file << "toolbar = {\n";
	for (auto* action : m_app.getToolbarActions())
	{
		file << "\t\"" << action->name << "\",\n";
	}
	file << "}\n";

	ImGui::SaveDock(file);

	file.close();

	return true;
}