The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
aspect_advancements.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2017 by Felix Bauer <fehlxb+wesnoth@gmail.com>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
16 
17 #include "log.hpp" // for LOG_STREAM, logger, etc
18 #include "lua/lauxlib.h" // for luaL_ref, LUA_REFNIL
19 #include "lua/lua.h" // for lua_isstring, etc
20 #include "map/location.hpp" // for map_location
21 #include "serialization/string_utils.hpp" // for split
22 #include "units/unit.hpp"
23 #include "units/map.hpp" // for unit_map::const_iterator, etc
24 
25 #include <ostream> // for operator<<, basic_ostream, etc
26 #include <string> // for string, char_traits, etc
27 #include <vector> // for vector
28 
29 struct lua_State;
30 
31 
32 
33 static lg::log_domain log_ai_engine_lua("ai/engine/lua");
34 #define LOG_LUA LOG_STREAM(info, log_ai_engine_lua)
35 #define ERR_LUA LOG_STREAM(err, log_ai_engine_lua)
36 
37 namespace ai{
38 
40  val_(), L_(),ref_()
41 {
42 }
43 
45  : val_("Lua Function")
46  , L_(L)
47  , ref_()
48 {
49  lua_settop(L, n);
50 
51  //on the top of the Lua-Stack is now the pointer to the function. Save it:
53 
54 }
55 
57 {
58 }
59 
61 {
62  if(L_) {
63  // Remove the function from the registry
65  }
66 }
67 
68 const std::vector<std::string> unit_advancements_aspect::get_advancements(const unit_map::const_iterator& unit) const
69 {
70 
71 
72  if(!unit.valid())
73  {
74  return std::vector<std::string>();
75  }
76 
77  const std::string& unit_id = (*unit).id();
78  const int unit_x = (*unit).get_location().wml_x();
79  const int unit_y = (*unit).get_location().wml_y();
80 
81  LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id << " on (x,y) = (" << unit_x << ", " << unit_y << ")\n";
82 
83  if(L_ == nullptr || ref_ == LUA_REFNIL)
84  {
85  //If we end up here, most likely the aspect don't use the lua-engine.
86  //Just to make sure:
87  if (val_ == "Lua Function")
88  {
89  return std::vector<std::string>();
90  }
91  return utils::split(val_);
92  }
93 
94  //put the Pointer back on the Stack
96 
97  if(lua_isstring(L_, -1))
98  {
99  return utils::split(lua_tostring(L_, -1));
100  }
101 
102  if(!lua_isfunction(L_, -1))
103  {
104  ERR_LUA << "Can't evaluate advancement aspect: Value is neither a string nor a function." << std::endl;
105  return std::vector<std::string>();
106  }
107 
108  //push parameter to the stack
109  lua_pushinteger(L_, unit_x);
110  lua_pushinteger(L_, unit_y);
111 
112  //To make unit_id a Parameter of the Lua function:
113  //lua_pushfstring(L_, unit_id.c_str());
114 
115  //call function
116  if(lua_pcall(L_, 2, 1, 0) != 0)
117  {
118  ERR_LUA << "LUA Error while evaluating advancements_aspect: " << lua_tostring(L_, -1) << std::endl;
119  return std::vector<std::string>();
120  }
121  if (!lua_isstring(L_, -1))
122  {
123  ERR_LUA << "LUA Error while evaluating advancements_aspect: Function must return String " << std::endl;
124  return std::vector<std::string>();
125  }
126 
127  //get result from Lua-Stack
128  const std::string retval = std::string(lua_tostring(L_, -1));
129  lua_pop(L_, 1);
130 
131  LOG_LUA << "Called Lua advancement function. Result was: \"" << retval << "\".\n";
132 
133  return utils::split(retval);
134 }
135 
136 
138 {
139  return val_;
140 }
141 }
static lg::log_domain log_ai_engine_lua("ai/engine/lua")
std::vector< char_t > string
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.cpp:172
This class represents a single unit of a specific type.
Definition: unit.hpp:101
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:657
LUALIB_API int luaL_ref(lua_State *L, int t)
Definition: lauxlib.cpp:595
#define val_(o)
Definition: lobject.h:123
#define LOG_LUA
std::vector< std::string > split(const std::string &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
#define lua_pop(L, n)
Definition: lua.h:344
#define lua_pcall(L, n, r, f)
Definition: lua.h:278
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:58
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:283
const std::vector< std::string > get_advancements(const unit_map::const_iterator &unit) const
#define ERR_LUA
#define lua_isfunction(L, n)
Definition: lua.h:352
#define lua_tostring(L, i)
Definition: lua.h:366
#define LUA_REGISTRYINDEX
Definition: lua.h:42
Standard logging facilities (interface).
const std::string get_value() const
LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
Definition: lauxlib.cpp:616
bool valid() const
Definition: map.hpp:276
static map_location::DIRECTION n
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:466
#define LUA_REFNIL
Definition: lauxlib.h:78