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