widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #09280
Re: [Merge] lp:~widelands-dev/widelands/feature-test-supply-crash into lp:widelands
Review: Approve
Added some tiny nits - feel free to merge any time once you have addressed them :)
Diff comments:
> === modified file 'src/scripting/lua_map.cc'
> --- src/scripting/lua_map.cc 2016-12-14 22:11:52 +0000
> +++ src/scripting/lua_map.cc 2017-01-06 09:18:41 +0000
> @@ -3974,7 +3977,233 @@
> WH_GET(ware, Ware)
> // documented in parent class
> WH_GET(worker, Worker)
> -#undef GET
> +#undef WH_GET
> +
> +// Transforms the given warehouse policy to a string which is used by the lua code
> +inline void wh_policy_to_string(lua_State* L, Warehouse::StockPolicy p) {
> + switch (p) {
> + case Warehouse::StockPolicy::SP_Normal:
> + lua_pushstring(L, "normal");
> + break;
> + case Warehouse::StockPolicy::SP_Prefer:
> + lua_pushstring(L, "prefer");
> + break;
> + case Warehouse::StockPolicy::SP_DontStock:
> + lua_pushstring(L, "dontstock");
> + break;
> + case Warehouse::StockPolicy::SP_Remove:
> + lua_pushstring(L, "remove");
> + break;
> + }
> +}
> +
> +// Transforms the given string from the lua code to a warehouse policy
> +inline Warehouse::StockPolicy string_to_wh_policy(lua_State* L, uint32_t index) {
> + std::string str = luaL_checkstring(L, index);
> + if (str == "normal")
> + return Warehouse::StockPolicy::SP_Normal;
> + else if (str == "prefer")
> + return Warehouse::StockPolicy::SP_Prefer;
> + else if (str == "dontstock")
> + return Warehouse::StockPolicy::SP_DontStock;
> + else if (str == "remove")
> + return Warehouse::StockPolicy::SP_Remove;
> + else
> + report_error(L, "<%s> is no valid warehouse policy!", str.c_str());
> +}
> +
> +bool do_set_ware_policy(Warehouse* wh, const DescriptionIndex idx, const Warehouse::StockPolicy p) {
> + wh->set_ware_policy(idx, p);
> + return true;
> +}
> +
> +/**
> + * Sets the given policy for the given ware in the given warehouse and return true.
> + * If the no ware with the given name exists for the tribe of the warehouse, return false.
> + */
> +bool do_set_ware_policy(Warehouse* wh, const std::string& name, const Warehouse::StockPolicy p) {
> + const TribeDescr& tribe = wh->owner().tribe();
> + DescriptionIndex idx = tribe.ware_index(name);
> + if (!tribe.has_ware(idx)) {
> + return false;
> + }
> + return do_set_ware_policy(wh, idx, p);
> +}
> +
> +bool do_set_worker_policy(Warehouse* wh,
> + const DescriptionIndex idx,
> + const Warehouse::StockPolicy p) {
> + const TribeDescr& tribe = wh->owner().tribe();
> + // If the worker does not cost anything, ignore it
> + // Otherwise, an unlimited stream of carriers might leave the warehouse
> + if (tribe.get_worker_descr(idx)->is_buildable() &&
> + tribe.get_worker_descr(idx)->buildcost().empty()) {
> + return true;
> + }
> + wh->set_worker_policy(idx, p);
> + return true;
> +}
> +
> +/**
> + * Sets the given policy for the given worker in the given warehouse and return true.
returns true
> + * Also return true if the given worker does not cost anything but do not set its policy.
returns true ... in this case does not
> + * If the no worker with the given name exists for the tribe of the warehouse, return false.
the no > no
> + */
> +bool do_set_worker_policy(Warehouse* wh, const std::string& name, const Warehouse::StockPolicy p) {
> + const TribeDescr& tribe = wh->owner().tribe();
> + DescriptionIndex idx = tribe.worker_index(name);
> + if (!tribe.has_worker(idx)) {
> + return false;
> + }
> + return do_set_worker_policy(wh, idx, p);
> +}
> +
> +/* RST
> + .. method:: set_warehouse_policies(which, policy)
> +
> + Sets the policies how the warehouse should handle the given wares.
wares/workers
> +
> + Usage example:
> + .. code-block:: lua
> +
> + wh:set_warehouse_policies("coal", "prefer")
> +
> + :arg which: behaves like for :meth:`HasWares.get_wares`.
> +
> + :arg policy: the policy to apply for all the wares given in `which`.
wares/workers
> + :type policy: a string out of "normal", "prefer", "dontstock", "remove".
> +*/
> +int LuaWarehouse::set_warehouse_policies(lua_State* L) {
> + int32_t nargs = lua_gettop(L);
> + if (nargs != 3)
> + report_error(L, "Wrong number of arguments to set_warehouse_policies!");
> +
> + Warehouse* wh = get(L, get_egbase(L));
> + Warehouse::StockPolicy p = string_to_wh_policy(L, -1);
> + lua_pop(L, 1);
> + const TribeDescr& tribe = wh->owner().tribe();
> +
> + // takes either "all", a name or an array of names
> + if (lua_isstring(L, 2)) {
> + const std::string& what = luaL_checkstring(L, -1);
> + if (what == "all") {
> + for (const DescriptionIndex& i : tribe.wares()) {
> + do_set_ware_policy(wh, i, p);
> + }
> + for (const DescriptionIndex& i : tribe.workers()) {
> + do_set_worker_policy(wh, i, p);
> + }
> + } else {
> + // Only one item requested
> + if (!do_set_ware_policy(wh, what, p) && !do_set_worker_policy(wh, what, p)) {
> + // Unknown whatever, abort
> + report_error(L, "Unknown name: <%s>", what.c_str());
> + }
> + }
> + } else {
> + // array of names
> + luaL_checktype(L, 2, LUA_TTABLE);
> + lua_pushnil(L);
> + while (lua_next(L, 2) != 0) {
> + const std::string& what = luaL_checkstring(L, -1);
> + if (!do_set_ware_policy(wh, what, p) && !do_set_worker_policy(wh, what, p)) {
> + // Note that this will change the policy for entries earlier in the list
> + // but when the user provides broken data its his own fault
> + report_error(L, "Unknown name: <%s>", what.c_str());
> + }
> + lua_pop(L, 1);
> + }
> + }
> +
> + return 0;
> +}
> +
> +// Gets the warehouse policy by ware/worker-name or id
> +#define WH_GET_POLICY(type) \
> + void do_get_##type##_policy(lua_State* L, Warehouse* wh, const DescriptionIndex idx) { \
> + wh_policy_to_string(L, wh->get_##type##_policy(idx)); \
> + } \
> + \
> + bool do_get_##type##_policy(lua_State* L, Warehouse* wh, const std::string& name) { \
> + const TribeDescr& tribe = wh->owner().tribe(); \
> + DescriptionIndex idx = tribe.type##_index(name); \
> + if (!tribe.has_##type(idx)) { \
> + return false; \
> + } \
> + do_get_##type##_policy(L, wh, idx); \
> + return true; \
> + }
> +
> +WH_GET_POLICY(ware)
> +WH_GET_POLICY(worker)
> +#undef WH_GET_POLICY
> +
> +/* RST
> + .. method:: get_warehouse_policies(which)
> +
> + Gets the policies how the warehouse should handle the given wares.
wares/workers
> + The method to handle is one of the strings "normal", "prefer", "dontstock", "remove".
> +
> + Usage example:
> + .. code-block:: lua
> +
> + wh:get_warehouse_policies({"ax", "coal"})
> + -- Returns a table like {ax="normal", coal="prefer"}
> +
> + :arg which: behaves like for :meth:`HasWares.get_wares`.
> +
> + :returns: :class:`string` or :class:`table`
> +*/
> +int LuaWarehouse::get_warehouse_policies(lua_State* L) {
> + int32_t nargs = lua_gettop(L);
> + if (nargs != 2)
> + report_error(L, "Wrong number of arguments to get_warehouse_policies!");
> + Warehouse* wh = get(L, get_egbase(L));
> + const TribeDescr& tribe = wh->owner().tribe();
> + // takes either "all", a single name or an array of names
> + if (lua_isstring(L, 2)) {
> + std::string what = luaL_checkstring(L, -1);
> + if (what == "all") {
> + lua_newtable(L);
> + for (const DescriptionIndex& i : tribe.wares()) {
> + std::string name = tribe.get_ware_descr(i)->name();
> + lua_pushstring(L, name.c_str());
> + do_get_ware_policy(L, wh, i);
> + lua_rawset(L, -3);
> + }
> + for (const DescriptionIndex& i : tribe.workers()) {
> + std::string name = tribe.get_worker_descr(i)->name();
> + lua_pushstring(L, name.c_str());
> + do_get_worker_policy(L, wh, i);
> + lua_rawset(L, -3);
> + }
> + } else {
> + // Only one item requested
> + if (!do_get_ware_policy(L, wh, what) && !do_get_worker_policy(L, wh, what)) {
> + // Unknown whatever, abort
> + report_error(L, "Unknown name: <%s>", what.c_str());
> + }
> + }
> + } else {
> + // array of names
> + luaL_checktype(L, 2, LUA_TTABLE);
> + lua_newtable(L);
> + lua_pushnil(L);
> + while (lua_next(L, 2) != 0) {
> + // Stack is: ... input_table new_table nil input_key input_value
> + // input_value is the name of the ware or worker and will be added into the new table
> + // input_key is an index and is dropped by the next call of lua_next()
> + const std::string& what = luaL_checkstring(L, -1);
> + if (!do_get_ware_policy(L, wh, what) && !do_get_worker_policy(L, wh, what)) {
> + // Note that this will change the policy for entries earlier in the list
> + // but when the user provides broken data its his own fault
> + report_error(L, "Unknown name: <%s>", what.c_str());
> + }
> + lua_rawset(L, -4);
> + }
> + }
> + return 1;
> +}
>
> // documented in parent class
> int LuaWarehouse::get_soldiers(lua_State* L) {
--
https://code.launchpad.net/~widelands-dev/widelands/feature-test-supply-crash/+merge/312422
Your team Widelands Developers is subscribed to branch lp:~widelands-dev/widelands/feature-test-supply-crash.
References