You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
5.7 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2020 Ian McInerney <ian.s.mcinerney@ieee.org>
  5. * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
  6. * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.TXT for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. #ifndef KIID_H
  26. #define KIID_H
  27. #include <boost/uuid/uuid.hpp>
  28. #include <macros_swig.h>
  29. #include <nlohmann/json_fwd.hpp>
  30. #include <string>
  31. class wxString;
  32. /**
  33. * timestamp_t is our type to represent unique IDs for all kinds of elements;
  34. * historically simply the timestamp when they were created.
  35. *
  36. * Long term, this type might be renamed to something like unique_id_t
  37. * (and then rename all the methods from {Get,Set}TimeStamp()
  38. * to {Get,Set}Id()) ?
  39. */
  40. typedef uint32_t timestamp_t;
  41. class KIID
  42. {
  43. public:
  44. KIID();
  45. KIID( int null );
  46. KIID( const std::string& aString );
  47. KIID( const char* aString );
  48. KIID( const wxString& aString );
  49. KIID( timestamp_t aTimestamp );
  50. void Clone( const KIID& aUUID );
  51. size_t Hash() const;
  52. bool IsLegacyTimestamp() const;
  53. timestamp_t AsLegacyTimestamp() const;
  54. wxString AsString() const;
  55. wxString AsLegacyTimestampString() const;
  56. /**
  57. * Returns true if a string has the correct formatting to be a KIID.
  58. */
  59. static bool SniffTest( const wxString& aCandidate );
  60. /**
  61. * A performance optimization which disables/enables the generation of pseudo-random UUIDs.
  62. *
  63. * NB: uses a global. Not thread safe!
  64. */
  65. static void CreateNilUuids( bool aNil = true );
  66. /**
  67. * Re-initialize the UUID generator with a given seed (for testing or QA purposes)
  68. *
  69. * WARNING: Do not call this function from within KiCad or via a Python action plugin. It is
  70. * only to be used inside QA tests or in external Python scripts. Resetting the UUID generator
  71. * in the middle of a KiCad GUI run will potentially have harmful effects on file integrity.
  72. *
  73. * @param aSeed is a seed to pass to the boost::mt19937 pseudo-random number generator
  74. */
  75. static void SeedGenerator( unsigned int aSeed );
  76. /**
  77. * Change an existing time stamp based UUID into a true UUID.
  78. *
  79. * If this is not a time stamp based UUID, then no change is made.
  80. */
  81. void ConvertTimestampToUuid();
  82. /**
  83. * Generates a deterministic replacement for a given ID.
  84. *
  85. * NB: destroys uniform distribution! But it's the only thing we have when a deterministic
  86. * replacement for a duplicate ID is required.
  87. */
  88. void Increment();
  89. bool operator==( KIID const& rhs ) const
  90. {
  91. return m_uuid == rhs.m_uuid;
  92. }
  93. bool operator!=( KIID const& rhs ) const
  94. {
  95. return m_uuid != rhs.m_uuid;
  96. }
  97. bool operator<( KIID const& rhs ) const
  98. {
  99. return m_uuid < rhs.m_uuid;
  100. }
  101. bool operator>( KIID const& rhs ) const
  102. {
  103. return m_uuid > rhs.m_uuid;
  104. }
  105. private:
  106. boost::uuids::uuid m_uuid;
  107. timestamp_t m_cached_timestamp;
  108. };
  109. extern KIID niluuid;
  110. KIID& NilUuid();
  111. // declare KIID_VECT_LIST as std::vector<KIID> both for c++ and swig:
  112. DECL_VEC_FOR_SWIG( KIID_VECT_LIST, KIID )
  113. class KIID_PATH : public KIID_VECT_LIST
  114. {
  115. public:
  116. KIID_PATH()
  117. {
  118. }
  119. KIID_PATH( const wxString& aString );
  120. bool MakeRelativeTo( const KIID_PATH& aPath );
  121. /**
  122. * Test if \a aPath from the last path towards the first path.
  123. *
  124. * This is useful for testing for existing schematic symbol and sheet instances when
  125. * copying or adding a new sheet that is lower in the hierarchy than the current path.
  126. *
  127. * @param aPath is the path to compare this path against.
  128. * @return true if this path ends with \a aPath or false if it does not.
  129. */
  130. bool EndsWith( const KIID_PATH& aPath ) const;
  131. wxString AsString() const;
  132. bool operator==( KIID_PATH const& rhs ) const
  133. {
  134. if( size() != rhs.size() )
  135. return false;
  136. for( size_t i = 0; i < size(); ++i )
  137. {
  138. if( at( i ) != rhs.at( i ) )
  139. return false;
  140. }
  141. return true;
  142. }
  143. bool operator<( KIID_PATH const& rhs ) const
  144. {
  145. if( size() != rhs.size() )
  146. return size() < rhs.size();
  147. for( size_t i = 0; i < size(); ++i )
  148. {
  149. if( at( i ) < rhs.at( i ) )
  150. return true;
  151. if( at( i ) != rhs.at( i ) )
  152. return false;
  153. }
  154. return false;
  155. }
  156. };
  157. /**
  158. * RAII class to safely set/reset nil KIIDs for use in footprint/symbol loading
  159. */
  160. class KIID_NIL_SET_RESET
  161. {
  162. public:
  163. KIID_NIL_SET_RESET()
  164. {
  165. KIID::CreateNilUuids( true );
  166. };
  167. ~KIID_NIL_SET_RESET()
  168. {
  169. KIID::CreateNilUuids( false );
  170. }
  171. };
  172. void to_json( nlohmann::json& aJson, const KIID& aKIID );
  173. void from_json( const nlohmann::json& aJson, KIID& aKIID );
  174. #endif // KIID_H