diff --git a/src/material.cc b/src/material.cc index db8b7e3b74..63b1c5b157 100644 --- a/src/material.cc +++ b/src/material.cc @@ -140,15 +140,30 @@ void Material::Transmute(Composition::Ptr c) { } } +Resource::Ptr Material::PackageExtract(double qty, std::string new_package_name) { + if (qty > qty_) { + throw ValueError("Attempted to extract more quantity than exists."); + } + + qty_ -= qty; + Material::Ptr other(new Material(ctx_, qty, comp_, new_package_name)); + + // Decay called on the extracted material should have the same dt as for + // this material regardless of composition. + other->prev_decay_time_ = prev_decay_time_; + + tracker_.Extract(&other->tracker_); + return boost::static_pointer_cast(other); +} + void Material::ChangePackage(std::string new_package_name) { - if (new_package_name == package_name_ || ctx_ == NULL) { + if (ctx_ == NULL) { // no change needed return; } else if (new_package_name == Package::unpackaged_name()) { // unpackaged has functionally no restrictions package_name_ = new_package_name; - tracker_.Package(); return; } @@ -157,10 +172,10 @@ void Material::ChangePackage(std::string new_package_name) { double max = p->fill_max(); if (qty_ >= min && qty_ <= max) { package_name_ = new_package_name; - tracker_.Package(); } else { throw ValueError("Material quantity is outside of package fill limits."); } + tracker_.Package(); } void Material::Decay(int curr_time) { diff --git a/src/material.h b/src/material.h index 008f9fde06..7d08eae319 100644 --- a/src/material.h +++ b/src/material.h @@ -158,6 +158,9 @@ class Material: public Resource { virtual std::string package_name(); + virtual Resource::Ptr PackageExtract(double qty, + std::string new_package_name = Package::unpackaged_name()); + /// Changes the package id. Checks that the resource fits the package /// type minimum and maximum mass criteria. virtual void ChangePackage(std::string new_package_name = Package::unpackaged_name()); diff --git a/src/product.cc b/src/product.cc index 254624ca1b..f07fb73cd7 100644 --- a/src/product.cc +++ b/src/product.cc @@ -76,6 +76,18 @@ std::string Product::package_name() { return package_name_; } +Resource::Ptr Product::PackageExtract(double qty, std::string new_package_name) { + if (qty > quantity_) { + throw ValueError("Attempted to extract more quantity than exists."); + } + + quantity_ -= qty; + Product::Ptr other(new Product(ctx_, qty, quality_, new_package_name)); + + tracker_.Extract(&other->tracker_); + return boost::static_pointer_cast(other); +} + void Product::ChangePackage(std::string new_package_name) { if (new_package_name == package_name_ || ctx_ == NULL) { // no change needed diff --git a/src/product.h b/src/product.h index 99f4091d69..68d734093b 100644 --- a/src/product.h +++ b/src/product.h @@ -74,6 +74,8 @@ class Product : public Resource { /// Returns the package id. virtual std::string package_name(); + virtual Resource::Ptr PackageExtract(double qty, std::string new_package_name = Package::unpackaged_name()); + /// Changes the product's package id virtual void ChangePackage(std::string new_package_name = Package::unpackaged_name()); diff --git a/src/res_tracker.cc b/src/res_tracker.cc index f11b174be7..159fca7daf 100644 --- a/src/res_tracker.cc +++ b/src/res_tracker.cc @@ -50,15 +50,11 @@ void ResTracker::Extract(ResTracker* removed) { parent2_ = 0; Record(); + } removed->parent1_ = res_->state_id(); removed->parent2_ = 0; removed->tracked_ = tracked_; - } else { - removed->parent1_ = parent1_; - removed->parent2_ = parent2_; - removed->tracked_ = tracked_; - } removed->Record(); } @@ -82,8 +78,7 @@ void ResTracker::Package() { Record(); } -void ResTracker::Record(bool no_bump) { - if (!no_bump) { +void ResTracker::Record() { res_->BumpStateId(); ctx_->NewDatum("Resources") ->AddVal("ResourceId", res_->state_id()) @@ -97,7 +92,6 @@ void ResTracker::Record(bool no_bump) { ->AddVal("Parent1", parent1_) ->AddVal("Parent2", parent2_) ->Record(); - } res_->Record(ctx_); } diff --git a/src/res_tracker.h b/src/res_tracker.h index d0fa6372ce..c4e83b71e5 100644 --- a/src/res_tracker.h +++ b/src/res_tracker.h @@ -46,7 +46,7 @@ class ResTracker { void Package(); private: - void Record(bool no_bump = false); + void Record(); int parent1_; int parent2_; diff --git a/src/resource.h b/src/resource.h index 61949e7a56..38d753e0f1 100644 --- a/src/resource.h +++ b/src/resource.h @@ -94,6 +94,8 @@ class Resource { /// Returns the package id. virtual std::string package_name() { return Package::unpackaged_name(); }; + virtual Ptr PackageExtract(double qty, std::string new_package_name = Package::unpackaged_name()) = 0; + /// Changes the product's package id virtual void ChangePackage(std::string new_package_name = Package::unpackaged_name()) {}; @@ -107,6 +109,12 @@ class Resource { static int nextstate_id_; static int nextobj_id_; int state_id_; + // Setting the state id should only be done when extracting one resource + void state_id(int st_id) { + state_id_ = st_id; + } + + int obj_id_; }; @@ -144,8 +152,7 @@ std::vector Resource::Package(Package::Ptr pkg) { while (quantity() > 0 && quantity() >= pkg->fill_min()) { double pkg_fill = std::min(quantity(), fill_mass); - t_pkgd = boost::dynamic_pointer_cast(ExtractRes(pkg_fill)); - t_pkgd->ChangePackage(pkg->name()); + t_pkgd = boost::dynamic_pointer_cast(PackageExtract(pkg_fill, pkg->name())); ts_pkgd.push_back(t_pkgd); } return ts_pkgd;