The Battle for Wesnoth  1.15.2+dev
lua_kernel_base.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2018 by Chris Beck <render787@gmail.com>
3  Part of the Battle for Wesnoth Project https://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 
15 #pragma once
16 
17 #include <sstream>
18 #include <string>
19 #include <vector>
20 #include "utils/functional.hpp"
21 #include <cstdint>
22 
23 struct lua_State;
24 class config;
25 
27 public:
29  virtual ~lua_kernel_base();
30 
31  /** Runs a [lua] tag. Doesn't throw lua_error.*/
32  void run_lua_tag(const config& cfg);
33 
34  /** Runs a plain script. Doesn't throw lua_error.*/
35  void run(char const *prog, const std::string& name, int nArgs = 0);
36 
37  /** Runs a plain script, but reports errors by throwing lua_error.*/
38  void throwing_run(char const * prog, const std::string& name, int nArgs);
39 
40  /** Tests if a program resolves to an expression, and pretty prints it if it is, otherwise it runs it normally. Throws exceptions.*/
41  void interactive_run(char const * prog);
42 
43  /** Loads the `package` library into lua environment. Only in allow in `unsafe` modes. */
44  void load_package();
45  /** Loads the "core" library into the Lua environment. Without this, most Wesnoth Lua won't work.
46  * Cannot be called from the constructor because it needs to call virtual functions.
47  */
48  void load_core();
49 
50  /** Get tab completion strings */
51  std::vector<std::string> get_global_var_names();
52  std::vector<std::string> get_attribute_names(const std::string & var_path);
53 
54  /** User-visible name of the lua kernel that they are talking to */
55  virtual std::string my_name() { return "Basic Lua Kernel"; }
56 
57  /** Access / manipulate logging of lua kernel activities */
58  const std::stringstream & get_log() { cmd_log_.log_ << std::flush; return cmd_log_.log_; }
59  void clear_log() { cmd_log_.log_.str(""); cmd_log_.log_.clear(); }
60 
61  using external_log_type = std::function<void(const std::string &)>;
63 
64  /** Error reporting mechanisms, used by virtual methods protected_call and load_string*/
65  virtual void log_error(char const* msg, char const* context = "Lua error");
66  virtual void throw_exception(char const* msg, char const* context = "Lua error"); //throws game::lua_error
67 
68  typedef std::function<void(char const*, char const*)> error_handler;
69 
70  template<typename T>
71  static T& get_lua_kernel(lua_State *L)
72  {
73  return *static_cast<T*>(get_lua_kernel_base_ptr(L));
74  }
75 
76  virtual uint32_t get_random_seed();
77  lua_State * get_state() { return mState; }
78  void add_widget_definition(const std::string& type, const std::string& id) { registered_widget_definitions_.emplace_back(type, id); }
79 protected:
81 
82  /** Log implementation */
83  struct command_log {
84 
85  std::stringstream log_;
87 
89  : log_()
90  , external_log_(nullptr)
91  {}
92 
93  inline command_log & operator<< (const std::string & str) {
94  log_ << str;
95  if (external_log_) {
96  external_log_(str);
97  }
98  return *this;
99  }
100 
101  inline command_log & operator<< (char const* str) {
102  if (str != nullptr) {
103  log_ << str;
104  if (external_log_) {
105  external_log_(str);
106  }
107  }
108  return *this;
109  }
110  };
111 
113 
114  // Print text to the command log for this lua kernel. Used as a replacement impl for lua print.
115  int intf_print(lua_State * L);
116 
117  // Show the interactive lua console (for debugging purposes)
119 
120  // Execute a protected call. Error handler is called in case of an error, using syntax for log_error and throw_exception above. Returns true if successful.
121  bool protected_call(int nArgs, int nRets, error_handler);
122  // Execute a protected call, taking a lua_State as argument. For functions pushed into the lua environment, this version should be used, or the function cannot be used by coroutines without segfaulting (since they have a different lua_State pointer). This version is called by the above version.
123  static bool protected_call(lua_State * L, int nArgs, int nRets, error_handler);
124  // Load a string onto the stack as a function. Returns true if successful, error handler is called if not.
125  bool load_string(char const * prog, const std::string& name, error_handler);
126 
127  virtual bool protected_call(int nArgs, int nRets); // select default error handler polymorphically
128  virtual bool load_string(char const * prog, const std::string& name); // select default error handler polymorphically
129 
130  // dofile (using lua_fileops)
131  int intf_dofile(lua_State * L);
132 
133  // require (using lua_fileops, protected_call)
134  int intf_require(lua_State * L);
135 
136  int intf_kernel_type(lua_State* L);
137 
138  virtual int impl_game_config_get(lua_State* L);
139  virtual int impl_game_config_set(lua_State* L);
140 private:
142  std::vector<std::tuple<std::string, std::string>> registered_widget_definitions_;
143 };
void interactive_run(char const *prog)
Tests if a program resolves to an expression, and pretty prints it if it is, otherwise it runs it nor...
std::function< void(char const *, char const *)> error_handler
command_log & operator<<(const std::string &str)
std::vector< std::tuple< std::string, std::string > > registered_widget_definitions_
int intf_kernel_type(lua_State *L)
virtual ~lua_kernel_base()
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
void add_widget_definition(const std::string &type, const std::string &id)
static T & get_lua_kernel(lua_State *L)
void load_core()
Loads the "core" library into the Lua environment.
int intf_show_lua_console(lua_State *L)
void load_package()
Loads the package library into lua environment.
bool protected_call(int nArgs, int nRets, error_handler)
virtual int impl_game_config_get(lua_State *L)
Definition: pump.hpp:39
void run(char const *prog, const std::string &name, int nArgs=0)
Runs a plain script.
int intf_print(lua_State *L)
Replacement print function – instead of printing to std::cout, print to the command log...
void set_external_log(external_log_type lg)
virtual uint32_t get_random_seed()
static std::string flush(std::ostringstream &s)
Definition: reports.cpp:90
std::function< void(const std::string &)> external_log_type
virtual void log_error(char const *msg, char const *context="Lua error")
Error reporting mechanisms, used by virtual methods protected_call and load_string.
bool load_string(char const *prog, const std::string &name, error_handler)
virtual int impl_game_config_set(lua_State *L)
std::vector< std::string > get_global_var_names()
Get tab completion strings.
command_log cmd_log_
std::vector< std::string > get_attribute_names(const std::string &var_path)
Gets all attribute names of an extended variable name.
const std::stringstream & get_log()
Access / manipulate logging of lua kernel activities.
virtual void throw_exception(char const *msg, char const *context="Lua error")
lua_State * get_state()
virtual std::string my_name()
User-visible name of the lua kernel that they are talking to.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
int intf_dofile(lua_State *L)
Loads and executes a Lua file.
lua_State * mState
void throwing_run(char const *prog, const std::string &name, int nArgs)
Runs a plain script, but reports errors by throwing lua_error.
int intf_require(lua_State *L)
Loads and executes a Lua file, if there is no corresponding entry in wesnoth.package.
void run_lua_tag(const config &cfg)
Runs a [lua] tag.
static lua_kernel_base *& get_lua_kernel_base_ptr(lua_State *L)