2022-07-15 15:37:19 +00:00
# ifndef slic3r_ObjectID_hpp_
# define slic3r_ObjectID_hpp_
# include <cereal/access.hpp>
2024-01-26 12:18:10 +00:00
# include <cereal/types/base_class.hpp>
2022-07-15 15:37:19 +00:00
namespace Slic3r {
namespace UndoRedo {
class StackImpl ;
} ;
// Unique identifier of a mutable object accross the application.
// Used to synchronize the front end (UI) with the back end (BackgroundSlicingProcess / Print / PrintObject)
// (for Model, ModelObject, ModelVolume, ModelInstance or ModelMaterial classes)
// and to serialize / deserialize an object onto the Undo / Redo stack.
// Valid IDs are strictly positive (non zero).
// It is declared as an object, as some compilers (notably msvcc) consider a typedef size_t equivalent to size_t
// for parameter overload.
class ObjectID
{
public :
ObjectID ( size_t id ) : id ( id ) { }
// Default constructor constructs an invalid ObjectID.
ObjectID ( ) : id ( 0 ) { }
bool operator = = ( const ObjectID & rhs ) const { return this - > id = = rhs . id ; }
bool operator ! = ( const ObjectID & rhs ) const { return this - > id ! = rhs . id ; }
bool operator < ( const ObjectID & rhs ) const { return this - > id < rhs . id ; }
bool operator > ( const ObjectID & rhs ) const { return this - > id > rhs . id ; }
bool operator < = ( const ObjectID & rhs ) const { return this - > id < = rhs . id ; }
bool operator > = ( const ObjectID & rhs ) const { return this - > id > = rhs . id ; }
bool valid ( ) const { return id ! = 0 ; }
bool invalid ( ) const { return id = = 0 ; }
size_t id ;
private :
friend class cereal : : access ;
template < class Archive > void serialize ( Archive & ar ) { ar ( id ) ; }
} ;
// Base for Model, ModelObject, ModelVolume, ModelInstance or ModelMaterial to provide a unique ID
// to synchronize the front end (UI) with the back end (BackgroundSlicingProcess / Print / PrintObject).
// Also base for Print, PrintObject, SLAPrint, SLAPrintObject to provide a unique ID for matching Model / ModelObject
// with their corresponding Print / PrintObject objects by the notification center at the UI when processing back-end warnings.
// Achtung! The s_last_id counter is not thread safe, so it is expected, that the ObjectBase derived instances
// are only instantiated from the main thread.
class ObjectBase
{
public :
using Timestamp = uint64_t ;
ObjectID id ( ) const { return m_id ; }
// Return an optional timestamp of this object.
// If the timestamp returned is non-zero, then the serialization framework will
// only save this object on the Undo/Redo stack if the timestamp is different
// from the timestmap of the object at the top of the Undo / Redo stack.
virtual Timestamp timestamp ( ) const { return 0 ; }
protected :
// Constructors to be only called by derived classes.
// Default constructor to assign a unique ID.
ObjectBase ( ) : m_id ( generate_new_id ( ) ) { }
// Constructor with ignored int parameter to assign an invalid ID, to be replaced
// by an existing ID copied from elsewhere.
ObjectBase ( int ) : m_id ( ObjectID ( 0 ) ) { }
2023-03-14 02:42:42 +00:00
ObjectBase ( const ObjectID id ) : m_id ( id ) { }
2022-07-15 15:37:19 +00:00
// The class tree will have virtual tables and type information.
virtual ~ ObjectBase ( ) = default ;
// Use with caution!
void set_new_unique_id ( ) { m_id = generate_new_id ( ) ; }
void set_invalid_id ( ) { m_id = 0 ; }
// Use with caution!
void copy_id ( const ObjectBase & rhs ) { m_id = rhs . id ( ) ; }
// Override this method if a ObjectBase derived class owns other ObjectBase derived instances.
virtual void assign_new_unique_ids_recursive ( ) { this - > set_new_unique_id ( ) ; }
private :
ObjectID m_id ;
static inline ObjectID generate_new_id ( ) { return ObjectID ( + + s_last_id ) ; }
static size_t s_last_id ;
friend ObjectID wipe_tower_object_id ( ) ;
friend ObjectID wipe_tower_instance_id ( ) ;
friend class cereal : : access ;
friend class Slic3r : : UndoRedo : : StackImpl ;
template < class Archive > void serialize ( Archive & ar ) { ar ( m_id ) ; }
template < class Archive > static void load_and_construct ( Archive & ar , cereal : : construct < ObjectBase > & construct ) { ObjectID id ; ar ( id ) ; construct ( id ) ; }
} ;
class ObjectWithTimestamp : public ObjectBase
{
protected :
// Constructors to be only called by derived classes.
// Default constructor to assign a new timestamp unique to this object's history.
ObjectWithTimestamp ( ) = default ;
// Constructor with ignored int parameter to assign an invalid ID, to be replaced
// by an existing ID copied from elsewhere.
ObjectWithTimestamp ( int ) : ObjectBase ( - 1 ) { }
// The class tree will have virtual tables and type information.
virtual ~ ObjectWithTimestamp ( ) = default ;
// The timestamp uniquely identifies content of the derived class' data, therefore it makes sense to copy the timestamp if the content data was copied.
void copy_timestamp ( const ObjectWithTimestamp & rhs ) { m_timestamp = rhs . m_timestamp ; }
public :
// Return an optional timestamp of this object.
// If the timestamp returned is non-zero, then the serialization framework will
// only save this object on the Undo/Redo stack if the timestamp is different
// from the timestmap of the object at the top of the Undo / Redo stack.
Timestamp timestamp ( ) const throw ( ) override { return m_timestamp ; }
bool timestamp_matches ( const ObjectWithTimestamp & rhs ) const throw ( ) { return m_timestamp = = rhs . m_timestamp ; }
bool object_id_and_timestamp_match ( const ObjectWithTimestamp & rhs ) const throw ( ) { return this - > id ( ) = = rhs . id ( ) & & m_timestamp = = rhs . m_timestamp ; }
void touch ( ) { m_timestamp = + + s_last_timestamp ; }
private :
// The first timestamp is non-zero, as zero timestamp means the timestamp is not reliable.
Timestamp m_timestamp { 1 } ;
static Timestamp s_last_timestamp ;
friend class cereal : : access ;
friend class Slic3r : : UndoRedo : : StackImpl ;
template < class Archive > void serialize ( Archive & ar ) { ar ( m_timestamp ) ; }
} ;
2023-03-14 02:42:42 +00:00
class CutObjectBase : public ObjectBase
{
// check sum of CutParts in initial Object
size_t m_check_sum { 1 } ;
// connectors count
size_t m_connectors_cnt { 0 } ;
public :
// Default Constructor to assign an invalid ID
CutObjectBase ( ) : ObjectBase ( - 1 ) { }
// Constructor with ignored int parameter to assign an invalid ID, to be replaced
// by an existing ID copied from elsewhere.
CutObjectBase ( int ) : ObjectBase ( - 1 ) { }
// Constructor to initialize full information from 3mf
CutObjectBase ( ObjectID id , size_t check_sum , size_t connectors_cnt ) : ObjectBase ( id ) , m_check_sum ( check_sum ) , m_connectors_cnt ( connectors_cnt ) { }
// The class tree will have virtual tables and type information.
virtual ~ CutObjectBase ( ) = default ;
bool operator < ( const CutObjectBase & other ) const { return other . id ( ) > this - > id ( ) ; }
bool operator = = ( const CutObjectBase & other ) const { return other . id ( ) = = this - > id ( ) ; }
void copy ( const CutObjectBase & rhs )
{
this - > copy_id ( rhs ) ;
this - > m_check_sum = rhs . check_sum ( ) ;
this - > m_connectors_cnt = rhs . connectors_cnt ( ) ;
}
CutObjectBase & operator = ( const CutObjectBase & other )
{
this - > copy ( other ) ;
return * this ;
}
void invalidate ( )
{
set_invalid_id ( ) ;
m_check_sum = 1 ;
m_connectors_cnt = 0 ;
}
void init ( ) { this - > set_new_unique_id ( ) ; }
bool has_same_id ( const CutObjectBase & rhs ) { return this - > id ( ) = = rhs . id ( ) ; }
bool is_equal ( const CutObjectBase & rhs ) { return this - > id ( ) = = rhs . id ( ) & & this - > check_sum ( ) = = rhs . check_sum ( ) & & this - > connectors_cnt ( ) = = rhs . connectors_cnt ( ) ; }
size_t check_sum ( ) const { return m_check_sum ; }
void set_check_sum ( size_t cs ) { m_check_sum = cs ; }
void increase_check_sum ( size_t cnt ) { m_check_sum + = cnt ; }
size_t connectors_cnt ( ) const { return m_connectors_cnt ; }
void increase_connectors_cnt ( size_t connectors_cnt ) { m_connectors_cnt + = connectors_cnt ; }
private :
friend class cereal : : access ;
template < class Archive > void serialize ( Archive & ar )
{
ar ( cereal : : base_class < ObjectBase > ( this ) ) ;
ar ( m_check_sum , m_connectors_cnt ) ;
}
} ;
2022-07-15 15:37:19 +00:00
// Unique object / instance ID for the wipe tower.
extern ObjectID wipe_tower_object_id ( ) ;
extern ObjectID wipe_tower_instance_id ( ) ;
} // namespace Slic3r
# endif /* slic3r_ObjectID_hpp_ */