← Back to team overview

widelands-dev team mailing list archive

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