Commit add1dd2d authored by Jason Rhinelander's avatar Jason Rhinelander

Fix firm segfault: don't attempt to store things in trampoline

The trampoline class is never actually instantiated, it is only used
for it's methods.  The Firm trampoline was trying to expose the stored
bundles by copying a reference into the trampoline class, but for the
aforementioned reason this won't work.

Instead expose the protected fields via getter/setter methods.
parent 34e4c67f
......@@ -33,9 +33,9 @@ void bind_firm(py::module &m) {
.def("_produce", &PyFirm<>::produce, "bundle"_a, "Abstract method called when completing a reservation that requires production to satisfy some or all of the required output. `bundle` is the output required; returns the produced bundle that must be >= `bundle`. This method should not update _reserved_production, _excess_production, or the firm's assets: those will be updated appropriately based on the produced bundle")
.def("_reduce_excess_production", &PyFirm<>::reduceExcessProduction, "Abstract method called after cancelling a reserved transfer. This is essentially the opposite of reserve_production_: it should reduce any reserved production output as much as possible according to the excess planned production currently in excess_production_. For example, supposed a firm produces multiples of Bundle({ good1: 1, good2: 4 }) units, and has an internal variable indicating that 30 units may still be reserved for production before hitting a capacity constraint; if this is called with _excess_production containing 5 units each of good1 and good2, the firm would increase its available capacity by 1.25 and subtract Bundle({ good1 : 1.25, good2 : 5 }) from _excess_production.")
.def_readwrite("_reserves", &PyFirm<>::_reserves, py::return_value_policy::reference_internal, "This contains quantities removed from the assets() bundle that are covered by currently-pending reservations.")
.def_readwrite("_reserved_production", &PyFirm<>::_reserved_production, py::return_value_policy::reference_internal, "This contains quantities scheduled for production (as a result of currently-pending reservations) that will be produced when current reservations are completed.")
.def_readwrite("_excess_production", &PyFirm<>::_excess_production, py::return_value_policy::reference_internal, "This contains the amounts that will be produced to satisfy reserved production (due to reservations) but that is not actually part of the transferred quantity. Typically this results from a multiple-good production where the requested output units are not a perfect multiple of the production unit")
.def_property("_reserves", &PyFirm<>::_reserves, &PyFirm<>::_set_reserves)
.def_property("_reserved_production", &PyFirm<>::_reserved_production, &PyFirm<>::_set_reserved_production)
.def_property("_excess_production", &PyFirm<>::_excess_production, &PyFirm<>::_set_excess_production)
;
py::class_<FirmNoProd, SharedMember<FirmNoProd>, PyFirmNoProd<>> firm_noprod(m, "FirmNoProd", firm);
......
......@@ -35,10 +35,12 @@ public:
using PyAgent<Base>::reserves_;
using PyAgent<Base>::reserved_production_;
using PyAgent<Base>::excess_production_;
// Access the bundles stored in the parent
Bundle* _reserves{&reserves_};
Bundle* _reserved_production{&reserved_production_};
Bundle* _excess_production{&excess_production_};
Bundle &_reserves() { return reserves_; }
void _set_reserves(Bundle &set) { reserves_ = set; }
Bundle &_reserved_production() { return reserved_production_; }
void _set_reserved_production(Bundle &set) { reserved_production_ = set; }
Bundle &_excess_production() { return excess_production_; }
void _set_excess_production(Bundle &set) { excess_production_ = set; }
};
// Trampoline class for (abstract) FirmNoProd
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment