Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce size of class item: #36598

Merged
merged 1 commit into from
Jan 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/crafting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ int item::get_next_failure_point() const
debugmsg( "get_next_failure_point() called on non-craft '%s.' Aborting.", tname() );
return INT_MAX;
}
return next_failure_point >= 0 ? next_failure_point : INT_MAX;
return craft_data_->next_failure_point >= 0 ? craft_data_->next_failure_point : INT_MAX;
}

void item::set_next_failure_point( const player &crafter )
Expand All @@ -969,7 +969,7 @@ void item::set_next_failure_point( const player &crafter )
const int percent_left = 10000000 - item_counter;
const int failure_point_delta = crafter.crafting_success_roll( get_making() ) * percent_left;

next_failure_point = item_counter + failure_point_delta;
craft_data_->next_failure_point = item_counter + failure_point_delta;
}

static void destroy_random_component( item &craft, const player &crafter )
Expand Down Expand Up @@ -1036,7 +1036,7 @@ requirement_data item::get_continue_reqs() const
debugmsg( "get_continue_reqs() called on non-craft '%s.' Aborting.", tname() );
return requirement_data();
}
return requirement_data::continue_requirements( comps_used, components );
return requirement_data::continue_requirements( craft_data_->comps_used, components );
}

void item::inherit_flags( const item &parent )
Expand Down
43 changes: 25 additions & 18 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,10 @@ static const item *get_most_rotten_component( const item &craft )
item::item( const recipe *rec, int qty, std::list<item> items, std::vector<item_comp> selections )
: item( "craft", calendar::turn, qty )
{
making = rec;
craft_data_ = cata::make_value<craft_data>();
craft_data_->making = rec;
components = items;
comps_used = selections;
craft_data_->comps_used = selections;

if( is_food() ) {
active = true;
Expand Down Expand Up @@ -753,10 +754,10 @@ bool item::stacks_with( const item &rhs, bool check_components ) const
if( corpse != nullptr && rhs.corpse != nullptr && corpse->id != rhs.corpse->id ) {
return false;
}
if( is_craft() && rhs.is_craft() ) {
if( get_making().ident() != rhs.get_making().ident() ) {
return false;
}
if( craft_data_ || rhs.craft_data_ ) {
// In-progress crafts are always distinct items. Easier to handle for the player,
// and there shouldn't be that many items of this type around anyway.
return false;
}
if( check_components || is_comestible() || is_craft() ) {
//Only check if at least one item isn't using the default recipe or is comestible
Expand Down Expand Up @@ -2560,7 +2561,7 @@ void item::final_info( std::vector<iteminfo> &info, const iteminfo_query *parts,
"It is %d percent complete." );
const int percent_progress = item_counter / 100000;
info.push_back( iteminfo( "DESCRIPTION", string_format( desc,
making->result_name(),
craft_data_->making->result_name(),
percent_progress ) ) );
} else {
info.push_back( iteminfo( "DESCRIPTION", type->description.translated() ) );
Expand Down Expand Up @@ -3799,7 +3800,7 @@ std::string item::tname( unsigned int quantity, bool with_prefix, unsigned int t
} else if( is_armor() && has_clothing_mod() ) {
maintext = label( quantity ) + "+1";
} else if( is_craft() ) {
maintext = string_format( _( "in progress %s" ), making->result_name() );
maintext = string_format( _( "in progress %s" ), craft_data_->making->result_name() );
if( charges > 1 ) {
maintext += string_format( " (%d)", charges );
}
Expand Down Expand Up @@ -5713,7 +5714,7 @@ bool item::is_brewable() const
bool item::is_food_container() const
{
return ( !contents.empty() && contents.front().is_food() ) || ( is_craft() &&
making->create_result().is_food_container() );
craft_data_->making->create_result().is_food_container() );
}

bool item::has_temperature() const
Expand Down Expand Up @@ -6034,7 +6035,7 @@ bool item::is_salvageable() const

bool item::is_craft() const
{
return making != nullptr;
return craft_data_ != nullptr;
}

bool item::is_funnel_container( units::volume &bigger_than ) const
Expand Down Expand Up @@ -9451,37 +9452,43 @@ void item::set_favorite( const bool favorite )

const recipe &item::get_making() const
{
if( !making ) {
if( !craft_data_ ) {
debugmsg( "'%s' is not a craft or has a null recipe", tname() );
return recipe().ident().obj();
static const recipe dummy{};
return dummy;
}
return *making;
assert( craft_data_->making );
return *craft_data_->making;
}

void item::set_tools_to_continue( bool value )
{
tools_to_continue = value;
assert( craft_data_ );
craft_data_->tools_to_continue = value;
}

bool item::has_tools_to_continue() const
{
return tools_to_continue;
assert( craft_data_ );
return craft_data_->tools_to_continue;
}

void item::set_cached_tool_selections( const std::vector<comp_selection<tool_comp>> &selections )
{
cached_tool_selections = selections;
assert( craft_data_ );
craft_data_->cached_tool_selections = selections;
}

const std::vector<comp_selection<tool_comp>> &item::get_cached_tool_selections() const
{
return cached_tool_selections;
assert( craft_data_ );
return craft_data_->cached_tool_selections;
}

const cata::value_ptr<islot_comestible> &item::get_comestible() const
{
if( is_craft() ) {
return find_type( making->result() )->comestible;
return find_type( craft_data_->making->result() )->comestible;
} else {
return type->comestible;
}
Expand Down
31 changes: 22 additions & 9 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <utility>

#include "calendar.h"
#include "value_ptr.h"
#include "cata_utility.h"
#include "craft_command.h"
#include "debug.h"
Expand Down Expand Up @@ -42,12 +43,11 @@ namespace cata
{
template<typename T>
class optional;
template<typename T>
class value_ptr;
} // namespace cata
class nc_color;
class JsonIn;
class JsonOut;
class JsonObject;
class iteminfo_query;
template<typename T>
class ret_val;
Expand Down Expand Up @@ -2113,13 +2113,26 @@ class item : public visitable<item>
std::string corpse_name; // Name of the late lamented
std::set<matec_id> techniques; // item specific techniques

// Only for in-progress crafts
const recipe *making = nullptr;
int next_failure_point = -1;
std::vector<item_comp> comps_used;
// If the crafter has insufficient tools to continue to the next 5% progress step
bool tools_to_continue = false;
std::vector<comp_selection<tool_comp>> cached_tool_selections;
/**
* Data for items that represent in-progress crafts.
*/
class craft_data
{
public:
const recipe *making = nullptr;
int next_failure_point = -1;
std::vector<item_comp> comps_used;
// If the crafter has insufficient tools to continue to the next 5% progress step
bool tools_to_continue = false;
std::vector<comp_selection<tool_comp>> cached_tool_selections;

void serialize( JsonOut &jsout ) const;
void deserialize( JsonIn &jsin );
void deserialize( const JsonObject &obj );
};

cata::value_ptr<craft_data> craft_data_;

// any relic data specific to this item
cata::optional<relic> relic_data;
public:
Expand Down
56 changes: 44 additions & 12 deletions src/savegame_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2034,6 +2034,47 @@ void units::energy::deserialize( JsonIn &jsin )

static void migrate_toolmod( item &it );

void item::craft_data::serialize( JsonOut &jsout ) const
{
jsout.start_object();
jsout.member( "making", making->ident().str() );
jsout.member( "comps_used", comps_used );
jsout.member( "next_failure_point", next_failure_point );
jsout.member( "tools_to_continue", tools_to_continue );
jsout.member( "cached_tool_selections", cached_tool_selections );
jsout.end_object();
}

void item::craft_data::deserialize( JsonIn &jsin )
{
deserialize( jsin.get_object() );
}

void item::craft_data::deserialize( const JsonObject &obj )
{
making = &recipe_id( obj.get_string( "making" ) ).obj();
obj.read( "comps_used", comps_used );
next_failure_point = obj.get_int( "next_failure_point", -1 );
tools_to_continue = obj.get_bool( "tools_to_continue", false );
obj.read( "cached_tool_selections", cached_tool_selections );
}

// Template parameter because item::craft_data is private and I don't want to make it public.
template<typename T>
static void load_legacy_craft_data( io::JsonObjectInputArchive &archive, T &value )
{
if( archive.has_member( "making" ) ) {
value = cata::make_value<typename T::element_type>();
value->deserialize( archive );
}
}

// Dummy function as we never load anything from an output archive.
template<typename T>
static void load_legacy_craft_data( io::JsonObjectOutputArchive &, T & )
{
}

template<typename Archive>
void item::io( Archive &archive )
{
Expand All @@ -2055,10 +2096,6 @@ void item::io( Archive &archive )
corpse = &mtype_id( id ).obj();
}
};
const auto load_making = [this]( const std::string & id ) {
making = &recipe_id( id ).obj();
};

archive.template io<const itype>( "typeid", type, load_type, []( const itype & i ) {
return i.get_id();
}, io::required_tag() );
Expand Down Expand Up @@ -2109,17 +2146,10 @@ void item::io( Archive &archive )
[]( const mtype & i ) {
return i.id.str();
} );
archive.template io<const recipe>( "making", making, load_making,
[]( const recipe & i ) {
return i.ident().str();
} );
archive.io( "craft_data", craft_data_, decltype( craft_data_ )() );
archive.io( "light", light.luminance, nolight.luminance );
archive.io( "light_width", light.width, nolight.width );
archive.io( "light_dir", light.direction, nolight.direction );
archive.io( "comps_used", comps_used, io::empty_default_tag() );
archive.io( "next_failure_point", next_failure_point, -1 );
archive.io( "tools_to_continue", tools_to_continue, false );
archive.io( "cached_tool_selections", cached_tool_selections, io::empty_default_tag() );

archive.io( "relic_data", relic_data );

Expand All @@ -2130,6 +2160,8 @@ void item::io( Archive &archive )
}
/* Loading has finished, following code is to ensure consistency and fixes bugs in saves. */

load_legacy_craft_data( archive, craft_data_ );

double float_damage = 0;
if( archive.read( "damage", float_damage ) ) {
damage_ = std::min( std::max( min_damage(),
Expand Down
21 changes: 21 additions & 0 deletions src/value_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include <memory>

class JsonIn;
class JsonOut;

namespace cata
{

Expand All @@ -24,6 +27,24 @@ class value_ptr : public std::unique_ptr<T>
std::unique_ptr<T>::operator=( std::move( other ) );
return *this;
}

template<typename Stream = JsonOut>
void serialize( Stream &jsout ) const {
if( this->get() ) {
this->get()->serialize( jsout );
} else {
jsout.write_null();
}
}
template<typename Stream = JsonIn>
void deserialize( Stream &jsin ) {
if( jsin.test_null() ) {
this->reset();
} else {
this->reset( new T() );
this->get()->deserialize( jsin );
}
}
};

template <class T, class... Args>
Expand Down