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.

238 lines
6.2 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  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-2023 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 <kicommon.h>
  28. #include <boost/uuid/uuid.hpp>
  29. #include <macros_swig.h>
  30. #include <nlohmann/json_fwd.hpp>
  31. #include <string>
  32. class wxString;
  33. /**
  34. * timestamp_t is our type to represent unique IDs for all kinds of elements;
  35. * historically simply the timestamp when they were created.
  36. *
  37. * Long term, this type might be renamed to something like unique_id_t
  38. * (and then rename all the methods from {Get,Set}TimeStamp()
  39. * to {Get,Set}Id()) ?
  40. */
  41. typedef uint32_t timestamp_t;
  42. class KICOMMON_API KIID
  43. {
  44. public:
  45. KIID();
  46. KIID( int null );
  47. KIID( const std::string& aString );
  48. KIID( const char* aString );
  49. KIID( const wxString& aString );
  50. KIID( timestamp_t aTimestamp );
  51. void Clone( const KIID& aUUID );
  52. size_t Hash() const;
  53. bool IsLegacyTimestamp() const;
  54. timestamp_t AsLegacyTimestamp() const;
  55. wxString AsString() const;
  56. wxString AsLegacyTimestampString() const;
  57. std::string AsStdString() const;
  58. /**
  59. * Returns true if a string has the correct formatting to be a KIID.
  60. */
  61. static bool SniffTest( const wxString& aCandidate );
  62. /**
  63. * A performance optimization which disables/enables the generation of pseudo-random UUIDs.
  64. *
  65. * NB: uses a global. Not thread safe!
  66. */
  67. static void CreateNilUuids( bool aNil = true );
  68. /**
  69. * Re-initialize the UUID generator with a given seed (for testing or QA purposes)
  70. *
  71. * WARNING: Do not call this function from within KiCad or via a Python action plugin. It is
  72. * only to be used inside QA tests or in external Python scripts. Resetting the UUID generator
  73. * in the middle of a KiCad GUI run will potentially have harmful effects on file integrity.
  74. *
  75. * @param aSeed is a seed to pass to the boost::mt19937 pseudo-random number generator
  76. */
  77. static void SeedGenerator( unsigned int aSeed );
  78. /**
  79. * Change an existing time stamp based UUID into a true UUID.
  80. *
  81. * If this is not a time stamp based UUID, then no change is made.
  82. */
  83. void ConvertTimestampToUuid();
  84. /**
  85. * Generates a deterministic replacement for a given ID.
  86. *
  87. * NB: destroys uniform distribution! But it's the only thing we have when a deterministic
  88. * replacement for a duplicate ID is required.
  89. */
  90. void Increment();
  91. bool operator==( KIID const& rhs ) const
  92. {
  93. return m_uuid == rhs.m_uuid;
  94. }
  95. bool operator!=( KIID const& rhs ) const
  96. {
  97. return m_uuid != rhs.m_uuid;
  98. }
  99. bool operator<( KIID const& rhs ) const
  100. {
  101. return m_uuid < rhs.m_uuid;
  102. }
  103. bool operator>( KIID const& rhs ) const
  104. {
  105. return m_uuid > rhs.m_uuid;
  106. }
  107. private:
  108. boost::uuids::uuid m_uuid;
  109. };
  110. extern KICOMMON_API KIID niluuid;
  111. KICOMMON_API KIID& NilUuid();
  112. // declare KIID_VECT_LIST as std::vector<KIID> both for c++ and swig:
  113. DECL_VEC_FOR_SWIG( KIID_VECT_LIST, KIID )
  114. class KICOMMON_API KIID_PATH : public KIID_VECT_LIST
  115. {
  116. public:
  117. KIID_PATH()
  118. {
  119. }
  120. KIID_PATH( const wxString& aString );
  121. bool MakeRelativeTo( const KIID_PATH& aPath );
  122. /**
  123. * Test if \a aPath from the last path towards the first path.
  124. *
  125. * This is useful for testing for existing schematic symbol and sheet instances when
  126. * copying or adding a new sheet that is lower in the hierarchy than the current path.
  127. *
  128. * @param aPath is the path to compare this path against.
  129. * @return true if this path ends with \a aPath or false if it does not.
  130. */
  131. bool EndsWith( const KIID_PATH& aPath ) const;
  132. wxString AsString() const;
  133. bool operator==( KIID_PATH const& rhs ) const
  134. {
  135. if( size() != rhs.size() )
  136. return false;
  137. for( size_t i = 0; i < size(); ++i )
  138. {
  139. if( at( i ) != rhs.at( i ) )
  140. return false;
  141. }
  142. return true;
  143. }
  144. bool operator<( KIID_PATH const& rhs ) const
  145. {
  146. if( size() != rhs.size() )
  147. return size() < rhs.size();
  148. for( size_t i = 0; i < size(); ++i )
  149. {
  150. if( at( i ) < rhs.at( i ) )
  151. return true;
  152. if( at( i ) != rhs.at( i ) )
  153. return false;
  154. }
  155. return false;
  156. }
  157. KIID_PATH& operator+=( const KIID_PATH& aRhs )
  158. {
  159. for( const KIID& kiid : aRhs )
  160. emplace_back( kiid );
  161. return *this;
  162. }
  163. friend KIID_PATH operator+( KIID_PATH aLhs, const KIID_PATH& aRhs )
  164. {
  165. aLhs += aRhs;
  166. return aLhs;
  167. }
  168. };
  169. /**
  170. * RAII class to safely set/reset nil KIIDs for use in footprint/symbol loading
  171. */
  172. class KICOMMON_API KIID_NIL_SET_RESET
  173. {
  174. public:
  175. KIID_NIL_SET_RESET()
  176. {
  177. KIID::CreateNilUuids( true );
  178. };
  179. ~KIID_NIL_SET_RESET()
  180. {
  181. KIID::CreateNilUuids( false );
  182. }
  183. };
  184. KICOMMON_API void to_json( nlohmann::json& aJson, const KIID& aKIID );
  185. KICOMMON_API void from_json( const nlohmann::json& aJson, KIID& aKIID );
  186. template<> struct KICOMMON_API std::hash<KIID>
  187. {
  188. std::size_t operator()( const KIID& aId ) const
  189. {
  190. return aId.Hash();
  191. }
  192. };
  193. #endif // KIID_H