mqsdx  300.0.0
MQPluginSDK Extention Library / mqsdkをC++またはCLI(.Net)拡張するサポートライブラリ。
 全て クラス 関数 変数 プロパティ グループ ページ
MQ0x_11.hpp
1 /*
2 First author tiritomato 2013.
3 
4 mqsdx is distributed under the GNU Lesser General Public License(LGPL).
5 
6 support blog (Japanese only)
7 http://d.hatena.ne.jp/tiri_tomato/
8 */
9 
10 #pragma once
11 
12 namespace MQ0x { namespace { namespace prv_impl {
13 
14  template <typename T_MQOBJECT>
15  struct MQIndexedObjectIFBase {
16  const std::function<int (const MQDocument)> count_function;
17  const std::function<T_MQOBJECT(const MQDocument, int)> get_function;
18  protected:
19  MQIndexedObjectIFBase() {}
20  MQIndexedObjectIFBase( const std::function<int (const MQDocument)> _count_function,
21  const std::function<T_MQOBJECT(const MQDocument, int)> _get_function ) :
22  count_function( _count_function ), get_function( _get_function ) {}
23  };
24  template <typename T_MQOBJECT>
25  struct MQIndexedObjectIF : public MQIndexedObjectIFBase<T_MQOBJECT> {
26  private: MQIndexedObjectIF() : MQIndexedObjectIFBase() {}
27  };
28  template <>
29  struct MQIndexedObjectIF<MQObject> : public MQIndexedObjectIFBase<MQObject> {
30  MQIndexedObjectIF () : MQIndexedObjectIFBase (
31  [](const MQDocument doc) { return doc->GetObjectCount(); },
32  [](const MQDocument doc, int index) { return doc->GetObject(index); } ) {}
33  };
34  template <>
35  struct MQIndexedObjectIF<MQMaterial> : public MQIndexedObjectIFBase<MQMaterial> {
36  MQIndexedObjectIF () : MQIndexedObjectIFBase (
37  [](const MQDocument doc) { return doc->GetMaterialCount(); },
38  [](const MQDocument doc, int index) { return doc->GetMaterial(index); } ) {}
39  };
40  template <typename T_MQOBJECT>
41  struct MQIndexObjectCollection {
42  private:
43  MQIndexObjectCollection();
44  const MQIndexedObjectIF<T_MQOBJECT> functionObject;
45  const MQDocument m_doc;
46  public:
47  MQIndexObjectCollection( const MQDocument doc ) : functionObject(), m_doc( doc ) {}
48  int Count() {
49  if ( m_doc == NULL ) return 0;
50  return functionObject.count_function( m_doc );
51  }
52  T_MQOBJECT operator [] ( int index ) {
53  if ( m_doc == NULL ) return 0;
54  return functionObject.get_function( m_doc, index );
55  }
56  };
57 
58  template <typename T_MQOBJECT> inline
59  std::string GetCountUpCloneableUniqueName( const MQDocument doc, const T_MQOBJECT srcObj, std::vector<char>* const buf = NULL )
60  {
61  if ( buf == NULL ) {
62  std::vector<char> tmp;
63  return GetCountUpCloneableUniqueName( doc, srcObj, &tmp );
64  }
65 
66  std::string ret;
67  if ( doc != NULL && srcObj != NULL )
68  {
69  unsigned long trailNum = 0;
70  std::string prefix;
71  std::regex re("[0-9]+$");
72  std::match_results<const char *> results;
73  GetNamedName( srcObj, buf );
74  if ( std::regex_search( &(*buf)[0], results, re, std::regex_constants::match_default ) ) {
75  if ( 0 < results.str().length() ) {
76  char* end = NULL;
77  trailNum = ::strtoul( results.str().c_str(), &end, 10 );
78  }
79  prefix = results.prefix().str();
80  }
81  else prefix = &(*buf)[0];
82  do // find unique name
83  {
84  std::stringstream strstr;
85  strstr << std::setw( results.str().length() ) << std::setfill('0') << (trailNum += 1);
86  ret = prefix + strstr.str();
87  }
88  while ( GetNamed<T_MQOBJECT>(doc, ret.c_str() ) != NULL );
89  }
90  return ret;
91  }
93  template <typename T_MQNAMED> inline
94  size_t GetNamedNameImplement( const T_MQNAMED obj, std::vector<char>* const buf, const std::vector<char>::size_type initial_size )
95  {
96  // vector char pattern
97  std::vector<char>::size_type _initial_size = std::max(initial_size, (std::vector<char>::size_type)2); // 2 = one char + null char space
98  for ( buf->resize( std::max( buf->size(), _initial_size ), '\0' ); true; buf->resize( buf->size() * 2, '\0' ) )
99  {
100  obj->GetName( &(*buf)[0], buf->size() );
101  if ( (*buf)[buf->size() - 2] == '\0' ) return strlen(&(*buf)[0]);
102  }
103  return 0;
104  }
109  template <typename T_MQNAMED>
110  size_t GetNamedName( const T_MQNAMED obj, std::vector<char>* const buf = NULL,
111  const std::vector<char>::size_type initial_size = GetNameInitialBufferSize )
112  {
113  if ( obj == NULL ) return -1;
114  else if ( buf == NULL ) {
115  std::vector<char> tmp;
116  return GetNamedNameImplement( obj, &tmp, initial_size );
117  }
118  else return GetNamedNameImplement( obj, buf, initial_size );
119  }
120  template <typename T_MQOBJECT> inline std::string GetName( const T_MQOBJECT objNamed ) {
121  if ( objNamed == NULL ) return "";
122  std::vector<char> buf;
123  prv_impl::GetNamedName( objNamed, &buf );
124  return &buf[0];
125  }
126  template <typename T_MQNAMED> inline T_MQNAMED GetNamed( const MQDocument doc, const char* name ) {
127  if ( doc != NULL && name != NULL ) {
128  MQIndexObjectCollection<T_MQNAMED> namedObjects(doc);
129  std::vector<char> buf;
130  for ( int index = 0, ctObject = namedObjects.Count(); index < ctObject; index++ ) {
131  T_MQNAMED obj = namedObjects[index];
132  if ( obj != NULL ) {
133  GetNamedName(obj, &buf);
134  if ( ::strcmp(&buf[0], name) == 0 ) return obj;
135  }
136  }
137  }
138  return NULL;
139  }
140  template <typename T_MQNAMED> inline int GetNamedIndex( const MQDocument doc, const char* name ) {
141  if ( doc != NULL && name != NULL ) {
142  MQIndexObjectCollection<T_MQNAMED> namedObjects(doc);
143  std::vector<char> buf;
144  for ( int index = 0, ctObject = namedObjects.Count(); index < ctObject; index++ ) {
145  T_MQNAMED obj = namedObjects[index];
146  if ( obj != NULL ) {
147  GetNamedName(obj, &buf);
148  if ( ::strcmp(&buf[0], name) == 0 ) return index;
149  }
150  }
151  }
152  return -1;
153  }
154  template <typename T_MQIDENTIFIED> inline
155  T_MQIDENTIFIED GetIdentified( const MQDocument doc, const UINT id )
156  {
157  if ( doc != NULL ) {
158  MQIndexObjectCollection<T_MQIDENTIFIED> identifiedObjects(doc);
159  for ( int index = 0, ctObject = identifiedObjects.Count(); index < ctObject; index++ ) {
160  T_MQIDENTIFIED obj = identifiedObjects[index];
161  if ( obj != NULL && (obj->GetUniqueID() == id) ) return obj;
162  }
163  }
164  return NULL;
165  }
166  template <typename T_MQIDENTIFIED> inline
167  int GetIdentifiedIndex( const MQDocument doc, const UINT id )
168  {
169  if ( doc != NULL ) {
170  MQIndexObjectCollection<T_MQIDENTIFIED> identifiedObjects(doc);
171  for ( int index = 0, ctObject = identifiedObjects.Count(); index < ctObject; index++ ) {
172  T_MQIDENTIFIED obj = identifiedObjects[index];
173  if ( obj != NULL && (obj->GetUniqueID() == id) ) return index;
174  }
175  }
176  return -1;
177  }
178  template <typename T_MQIDENTIFIED> inline
179  int GetIdentifiedIndex( const MQDocument doc, const T_MQIDENTIFIED src )
180  {
181  if ( (doc != NULL) && (src!=NULL) ) return GetIdentifiedIndex<T_MQIDENTIFIED>( doc, src->GetUniqueID() );
182  return -1;
183  }
184  inline void GetMaterialTextureName( std::vector<char>* buf, const MQMaterial mat, DWORD map_type = MQMAPPING_TEXTURE ) {
185  if ( mat == NULL ) return;
186  // vector char pattern
187  const std::vector<char>::size_type _initial_size =
188 #ifdef _DEBUG
189  2; /* 2 = one char + null char space*/
190 #else
191  MAX_PATH;
192 #endif
193  for ( buf->resize( std::max( buf->size(), _initial_size ), '\0' ); true; buf->resize( buf->size() * 2, '\0' ) )
194  {
195  switch ( map_type ) {
196  case MQMAPPING_TEXTURE:
197  mat->GetTextureName( &(*buf)[0], buf->size() );
198  break;
199  case MQMAPPING_ALPHA:
200  mat->GetAlphaName( &(*buf)[0], buf->size() );
201  break;
202  case MQMAPPING_BUMP:
203  mat->GetBumpName( &(*buf)[0], buf->size() );
204  break;
205  default:
206  return;
207  }
208  if ( (*buf)[buf->size() - 2] == '\0' ) return;
209  }
210  }
211 
212 #if 0x0310 <= MQPLUGIN_VERSION
213  template <typename T_MQOBJECT> void get_unused_name_function(const MQDocument, char*, int, const char*);
214  template <> void get_unused_name_function<MQMaterial>(const MQDocument doc, char* buffer, int buffer_size, const char* base_name) {
215  doc->GetUnusedMaterialName(buffer,buffer_size,base_name);
216  }
217  template <> void get_unused_name_function<MQObject>(const MQDocument doc, char* buffer, int buffer_size, const char* base_name) {
218  doc->GetUnusedObjectName(buffer,buffer_size,base_name);
219  }
221  template <typename T_MQNAMED> inline
222  size_t GetUnusedNameImplement( const MQDocument doc, std::vector<char>* const buf, const std::vector<char>::size_type initial_size, const char* base_name )
223  {
224  std::vector<char>::size_type _initial_size = std::max(initial_size, (std::vector<char>::size_type)2); // 2 = one char + null char space
225  for ( buf->resize( std::max( buf->size(), _initial_size ), '\0' ); true; buf->resize( buf->size() * 2, '\0' ) )
226  {
227  get_unused_name_function<T_MQNAMED>( doc, &(*buf)[0], buf->size(), base_name );
228  if ( (*buf)[buf->size() - 2] == '\0' ) return strlen(&(*buf)[0]);
229  }
230  return 0;
231  }
236  template <typename T_MQNAMED> inline
237  size_t GetUnusedName( const MQDocument doc, const char* base_name, std::vector<char>* const buf = NULL,
238  const std::vector<char>::size_type initial_size = GetNameInitialBufferSize )
239  {
240  if ( doc == NULL ) return -1;
241  else if ( buf == NULL ) {
242  std::vector<char> tmp;
243  return GetUnusedNameImplement<T_MQNAMED>( doc, &tmp, initial_size, base_name );
244  }
245  return GetUnusedNameImplement<T_MQNAMED>( doc, buf, initial_size, base_name );
246  }
247  template <typename T_MQNAMED> inline
248  std::string GetUnusedNameString( const MQDocument doc, const char* base_name = NULL ) {
249  if ( doc == NULL ) return "";
250  std::vector<char> tmp;
251  if ( GetUnusedName<T_MQNAMED>( doc, base_name, &tmp ) <= 0 ) return "";
252  return &tmp[0];
253  }
254 #endif
255 
256 }}}