Skip to content

Commit

Permalink
add wesnoth.colors
Browse files Browse the repository at this point in the history
see #3706

the main usecase to be able to show messages and
dialog labels in the color of a specific team.
  • Loading branch information
gfgtdf committed Mar 15, 2020
1 parent f166e2e commit f9790bc
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 0 deletions.
3 changes: 3 additions & 0 deletions projectfiles/VC14/wesnoth.vcxproj
Expand Up @@ -2624,6 +2624,9 @@
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|Win32'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|Win32'">$(IntDir)Scripting\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\scripting\lua_color.cpp">
<ObjectFileName>$(IntDir)Scripting\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\scripting\lua_common.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='ReleaseDEBUG|Win32'">$(IntDir)Scripting\</ObjectFileName>
Expand Down
4 changes: 4 additions & 0 deletions projectfiles/VC16/wesnoth.vcxproj
Expand Up @@ -2634,6 +2634,9 @@
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|x64'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|x64'">$(IntDir)Scripting\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\scripting\lua_color.cpp">
<ObjectFileName>$(IntDir)Scripting\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\scripting\lua_common.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)Scripting\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='ReleaseDEBUG|x64'">$(IntDir)Scripting\</ObjectFileName>
Expand Down Expand Up @@ -3981,6 +3984,7 @@
<ClInclude Include="..\..\src\scripting\debug_lua.hpp" />
<ClInclude Include="..\..\src\scripting\game_lua_kernel.hpp" />
<ClInclude Include="..\..\src\scripting\lua_audio.hpp" />
<ClInclude Include="..\..\src\scripting\lua_color.hpp" />
<ClInclude Include="..\..\src\scripting\lua_common.hpp" />
<ClInclude Include="..\..\src\scripting\lua_cpp_function.hpp" />
<ClInclude Include="..\..\src\scripting\lua_fileops.hpp" />
Expand Down
1 change: 1 addition & 0 deletions source_lists/wesnoth
Expand Up @@ -310,6 +310,7 @@ scripting/application_lua_kernel.cpp
scripting/debug_lua.cpp
scripting/game_lua_kernel.cpp
scripting/lua_audio.cpp
scripting/lua_color.cpp
scripting/lua_common.cpp
scripting/lua_cpp_function.cpp
scripting/lua_fileops.cpp
Expand Down
174 changes: 174 additions & 0 deletions src/scripting/lua_color.cpp
@@ -0,0 +1,174 @@
/*
Copyright (C) 2020-2020 by the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/

#include "color_range.hpp"
#include "scripting/lua_color.hpp"
#include "scripting/lua_common.hpp"
#include "scripting/push_check.hpp"
#include "lua/lauxlib.h"
#include "lua/lua.h" // for lua_State, lua_settop, etc
#include "log.hpp"
#include "game_config.hpp"

static lg::log_domain log_scripting_lua("scripting/lua");
#define LOG_LUA LOG_STREAM(info, log_scripting_lua)
#define ERR_LUA LOG_STREAM(err, log_scripting_lua)

static const char colorKey[] = "color range";

bool luaW_iscolor(lua_State* L, int index)
{
return luaL_testudata(L, index, colorKey) != nullptr;
}

static color_range& LuaW_checkcolor(lua_State *L, int index)
{
if(!luaW_iscolor(L, index)) {
luaW_type_error(L, index, "color");
throw "luaW_type_error returned";
}
return *static_cast<color_range*>(lua_touserdata(L, index));
}


color_range* luaW_pushcolor(lua_State *L, const color_range& color)
{
color_range* res = new(L) color_range(color);
luaL_setmetatable(L, colorKey);
return res;
}

int luaW_pushsinglecolor(lua_State *L, const color_t& color)
{
lua_createtable(L, 0, 4);
luaW_table_set(L, -1, "r", color.r);
luaW_table_set(L, -1, "g", color.g);
luaW_table_set(L, -1, "b", color.b);
luaW_table_set(L, -1, "a", color.a);
return 1;
}

static int impl_color_collect(lua_State *L)
{
color_range *c = static_cast<color_range *>(lua_touserdata(L, 1));
c->color_range::~color_range();
return 0;
}

/**
* Checks two color units for equality. (__eq metamethod)
*/
static int impl_color_equality(lua_State* L)
{
color_range& left = LuaW_checkcolor(L, 1);
color_range& right = LuaW_checkcolor(L, 2);
const bool equal = left == right;
lua_pushboolean(L, equal);
return 1;
}

/**
* Turns a lua color to string. (__tostring metamethod)
*/
static int impl_color_tostring(lua_State* L)
{
color_range& c = LuaW_checkcolor(L, 1);
//TODO: is this the best way to call tostring?
lua_push(L, c.debug());
return 1;
}


/**
* - Arg 1: userdata (ignored).
* - Arg 2: string containing the name of the color.
* - Ret 1: color_range containing the color.
*/
static int impl_get_color(lua_State *L)
{
std::string color_id = luaL_checkstring(L, 2);
luaW_pushcolor(L, game_config::color_info(color_id));
return 1;
}

static int impl_color_get(lua_State *L)
{
color_range& c = LuaW_checkcolor(L, 1);
char const *m = luaL_checkstring(L, 2);

if(strcmp(m, "min") == 0) {
return luaW_pushsinglecolor(L, c.min());
}
if(strcmp(m, "max") == 0) {
return luaW_pushsinglecolor(L, c.max());
}
if(strcmp(m, "mid") == 0) {
return luaW_pushsinglecolor(L, c.mid());
}
if(strcmp(m, "minimap") == 0) {
return luaW_pushsinglecolor(L, c.rep());
}
// TODO: i think this shortcut would be useful, but im not sure yet on the best attribute name.
//if(strcmp(m, "pango_hex") == 0) {
// lua_push(L, c.mid().to_hex_string());
// return 1;
//}
return 0;
}

static int impl_color_set(lua_State *L)
{
return luaL_argerror(L, 2, "color objects canot be modified");
}

namespace lua_colors {
std::string register_metatables(lua_State* L)
{
std::ostringstream cmd_out;

// Create the getunit metatable.
cmd_out << "Adding color metatable...\n";

luaL_newmetatable(L, colorKey);
lua_pushcfunction(L, impl_color_collect);
lua_setfield(L, -2, "__gc");
lua_pushcfunction(L, impl_color_equality);
lua_setfield(L, -2, "__eq");
lua_pushcfunction(L, impl_color_tostring);
lua_setfield(L, -2, "__tostring");
lua_pushcfunction(L, impl_color_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, impl_color_set);
lua_setfield(L, -2, "__newindex");
lua_pushstring(L, "color range");
lua_setfield(L, -2, "__metatable");


// Create the current variable with its metatable.
cmd_out << "Adding wesnoth.colors table...\n";

lua_getglobal(L, "wesnoth");
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, impl_get_color);
lua_setfield(L, -2, "__index");
lua_pushstring(L, "colors table");
lua_setfield(L, -2, "__metatable");
lua_setmetatable(L, -2);
lua_setfield(L, -2, "colors");
lua_pop(L, 1);

return cmd_out.str();
}
}

19 changes: 19 additions & 0 deletions src/scripting/lua_color.hpp
@@ -0,0 +1,19 @@
/*
Copyright (C) 2020-2020 by the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/

#include <string>
struct lua_State;

namespace lua_colors {
std::string register_metatables(lua_State* L);
}
3 changes: 3 additions & 0 deletions src/scripting/lua_kernel_base.cpp
Expand Up @@ -28,6 +28,7 @@
#include "scripting/debug_lua.hpp"
#endif

#include "scripting/lua_color.hpp"
#include "scripting/lua_common.hpp"
#include "scripting/lua_cpp_function.hpp"
#include "scripting/lua_fileops.hpp"
Expand Down Expand Up @@ -570,6 +571,8 @@ lua_kernel_base::lua_kernel_base()
// Create formula bridge metatables
cmd_log_ << lua_formula_bridge::register_metatables(L);

cmd_log_ << lua_colors::register_metatables(L);

// Create the Lua interpreter table
cmd_log_ << "Sandboxing Lua interpreter...\nTo make variables visible outside the interpreter, assign to _G.variable.\n";
cmd_log_ << "The special variable _ holds the result of the last expression (if any).\n";
Expand Down
14 changes: 14 additions & 0 deletions src/scripting/push_check.hpp
Expand Up @@ -397,3 +397,17 @@ lua_check_impl::remove_constref<T> luaW_table_get_def(lua_State *L, int index, u
lua_pop(L, 1);
return res;
}


template<typename T>
void luaW_table_set(lua_State *L, int index, utils::string_view k, const T& value)
{
if(!lua_istable(L, index)) {
luaL_argerror(L, index, "table expected");
}

index = lua_absindex(L, index);
lua_pushlstring(L, k.data(), k.size());
lua_push(L, value);
lua_settable(L, index);
}

0 comments on commit f9790bc

Please sign in to comment.