/sources/impl/scriptstring.cpp

https://github.com/Onagiro/HPL1Engine · C++ · 733 lines · 541 code · 116 blank · 76 comment · 7 complexity · b6822b32088750c12836e89f47368cd1 MD5 · raw file

  1. #include <assert.h>
  2. #include <string.h>
  3. #include <sstream>
  4. #include "impl/scriptstring.h"
  5. using namespace std;
  6. BEGIN_AS_NAMESPACE
  7. //--------------
  8. // constructors
  9. //--------------
  10. asCScriptString::asCScriptString()
  11. {
  12. // Count the first reference
  13. refCount = 1;
  14. }
  15. asCScriptString::asCScriptString(const char *s)
  16. {
  17. refCount = 1;
  18. buffer = s;
  19. }
  20. asCScriptString::asCScriptString(const string &s)
  21. {
  22. refCount = 1;
  23. buffer = s;
  24. }
  25. asCScriptString::asCScriptString(const asCScriptString &s)
  26. {
  27. refCount = 1;
  28. buffer = s.buffer;
  29. }
  30. asCScriptString::~asCScriptString()
  31. {
  32. assert( refCount == 0 );
  33. }
  34. //--------------------
  35. // reference counting
  36. //--------------------
  37. void asCScriptString::AddRef()
  38. {
  39. refCount++;
  40. }
  41. static void StringAddRef_Generic(asIScriptGeneric *gen)
  42. {
  43. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  44. thisPointer->AddRef();
  45. }
  46. void asCScriptString::Release()
  47. {
  48. if( --refCount == 0 )
  49. delete this;
  50. }
  51. static void StringRelease_Generic(asIScriptGeneric *gen)
  52. {
  53. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  54. thisPointer->Release();
  55. }
  56. //-----------------
  57. // string = string
  58. //-----------------
  59. asCScriptString &asCScriptString::operator=(const asCScriptString &other)
  60. {
  61. // Copy only the buffer, not the reference counter
  62. buffer = other.buffer;
  63. // Return a reference to this object
  64. return *this;
  65. }
  66. static void AssignString_Generic(asIScriptGeneric *gen)
  67. {
  68. asCScriptString *a = (asCScriptString*)gen->GetArgAddress(0);
  69. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  70. *thisPointer = *a;
  71. gen->SetReturnAddress(thisPointer);
  72. }
  73. //------------------
  74. // string += string
  75. //------------------
  76. asCScriptString &asCScriptString::operator+=(const asCScriptString &other)
  77. {
  78. buffer += other.buffer;
  79. return *this;
  80. }
  81. static void AddAssignString_Generic(asIScriptGeneric *gen)
  82. {
  83. asCScriptString *a = (asCScriptString*)gen->GetArgAddress(0);
  84. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  85. *thisPointer += *a;
  86. gen->SetReturnAddress(thisPointer);
  87. }
  88. //-----------------
  89. // string + string
  90. //-----------------
  91. asCScriptString *operator+(const asCScriptString &a, const asCScriptString &b)
  92. {
  93. // Return a new object as a script handle
  94. return new asCScriptString(a.buffer + b.buffer);
  95. }
  96. static void ConcatenateStrings_Generic(asIScriptGeneric *gen)
  97. {
  98. asCScriptString *a = (asCScriptString*)gen->GetArgAddress(0);
  99. asCScriptString *b = (asCScriptString*)gen->GetArgAddress(1);
  100. asCScriptString *out = *a + *b;
  101. gen->SetReturnAddress(out);
  102. }
  103. //----------------
  104. // string = value
  105. //----------------
  106. static asCScriptString &AssignBitsToString(asDWORD i, asCScriptString &dest)
  107. {
  108. ostringstream stream;
  109. stream << hex << i;
  110. dest.buffer = stream.str();
  111. // Return a reference to the object
  112. return dest;
  113. }
  114. static void AssignBitsToString_Generic(asIScriptGeneric *gen)
  115. {
  116. asDWORD i = gen->GetArgDWord(0);
  117. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  118. AssignBitsToString(i, *thisPointer);
  119. gen->SetReturnAddress(thisPointer);
  120. }
  121. static asCScriptString &AssignUIntToString(unsigned int i, asCScriptString &dest)
  122. {
  123. ostringstream stream;
  124. stream << i;
  125. dest.buffer = stream.str();
  126. return dest;
  127. }
  128. static void AssignUIntToString_Generic(asIScriptGeneric *gen)
  129. {
  130. unsigned int i = gen->GetArgDWord(0);
  131. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  132. AssignUIntToString(i, *thisPointer);
  133. gen->SetReturnAddress(thisPointer);
  134. }
  135. static asCScriptString &AssignIntToString(int i, asCScriptString &dest)
  136. {
  137. ostringstream stream;
  138. stream << i;
  139. dest.buffer = stream.str();
  140. return dest;
  141. }
  142. static void AssignIntToString_Generic(asIScriptGeneric *gen)
  143. {
  144. int i = gen->GetArgDWord(0);
  145. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  146. AssignIntToString(i, *thisPointer);
  147. gen->SetReturnAddress(thisPointer);
  148. }
  149. static asCScriptString &AssignFloatToString(float f, asCScriptString &dest)
  150. {
  151. ostringstream stream;
  152. stream << f;
  153. dest.buffer = stream.str();
  154. return dest;
  155. }
  156. static void AssignFloatToString_Generic(asIScriptGeneric *gen)
  157. {
  158. float f = gen->GetArgFloat(0);
  159. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  160. AssignFloatToString(f, *thisPointer);
  161. gen->SetReturnAddress(thisPointer);
  162. }
  163. static asCScriptString &AssignDoubleToString(double f, asCScriptString &dest)
  164. {
  165. ostringstream stream;
  166. stream << f;
  167. dest.buffer = stream.str();
  168. return dest;
  169. }
  170. static void AssignDoubleToString_Generic(asIScriptGeneric *gen)
  171. {
  172. double f = gen->GetArgDouble(0);
  173. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  174. AssignDoubleToString(f, *thisPointer);
  175. gen->SetReturnAddress(thisPointer);
  176. }
  177. //-----------------
  178. // string += value
  179. //-----------------
  180. static asCScriptString &AddAssignBitsToString(asDWORD i, asCScriptString &dest)
  181. {
  182. ostringstream stream;
  183. stream << hex << i;
  184. dest.buffer += stream.str();
  185. return dest;
  186. }
  187. static void AddAssignBitsToString_Generic(asIScriptGeneric *gen)
  188. {
  189. asDWORD i = gen->GetArgDWord(0);
  190. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  191. AddAssignBitsToString(i, *thisPointer);
  192. gen->SetReturnAddress(thisPointer);
  193. }
  194. static asCScriptString &AddAssignUIntToString(unsigned int i, asCScriptString &dest)
  195. {
  196. ostringstream stream;
  197. stream << i;
  198. dest.buffer += stream.str();
  199. return dest;
  200. }
  201. static void AddAssignUIntToString_Generic(asIScriptGeneric *gen)
  202. {
  203. unsigned int i = gen->GetArgDWord(0);
  204. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  205. AddAssignUIntToString(i, *thisPointer);
  206. gen->SetReturnAddress(thisPointer);
  207. }
  208. static asCScriptString &AddAssignIntToString(int i, asCScriptString &dest)
  209. {
  210. ostringstream stream;
  211. stream << i;
  212. dest.buffer += stream.str();
  213. return dest;
  214. }
  215. static void AddAssignIntToString_Generic(asIScriptGeneric *gen)
  216. {
  217. int i = gen->GetArgDWord(0);
  218. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  219. AddAssignIntToString(i, *thisPointer);
  220. gen->SetReturnAddress(thisPointer);
  221. }
  222. static asCScriptString &AddAssignFloatToString(float f, asCScriptString &dest)
  223. {
  224. ostringstream stream;
  225. stream << f;
  226. dest.buffer += stream.str();
  227. return dest;
  228. }
  229. static void AddAssignFloatToString_Generic(asIScriptGeneric *gen)
  230. {
  231. float f = gen->GetArgFloat(0);
  232. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  233. AddAssignFloatToString(f, *thisPointer);
  234. gen->SetReturnAddress(thisPointer);
  235. }
  236. static asCScriptString &AddAssignDoubleToString(double f, asCScriptString &dest)
  237. {
  238. ostringstream stream;
  239. stream << f;
  240. dest.buffer += stream.str();
  241. return dest;
  242. }
  243. static void AddAssignDoubleToString_Generic(asIScriptGeneric *gen)
  244. {
  245. double f = gen->GetArgDouble(0);
  246. asCScriptString *thisPointer = (asCScriptString*)gen->GetObject();
  247. AddAssignDoubleToString(f, *thisPointer);
  248. gen->SetReturnAddress(thisPointer);
  249. }
  250. //----------------
  251. // string + value
  252. //----------------
  253. static asCScriptString *AddStringBits(const asCScriptString &str, asDWORD i)
  254. {
  255. ostringstream stream;
  256. stream << hex << i;
  257. return new asCScriptString(str.buffer + stream.str());
  258. }
  259. static void AddStringBits_Generic(asIScriptGeneric *gen)
  260. {
  261. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(0);
  262. asDWORD i = gen->GetArgDWord(1);
  263. asCScriptString *out = AddStringBits(*str, i);
  264. gen->SetReturnAddress(out);
  265. }
  266. static asCScriptString *AddStringUInt(const asCScriptString &str, unsigned int i)
  267. {
  268. ostringstream stream;
  269. stream << i;
  270. return new asCScriptString(str.buffer + stream.str());
  271. }
  272. static void AddStringUInt_Generic(asIScriptGeneric *gen)
  273. {
  274. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(0);
  275. unsigned int i = gen->GetArgDWord(1);
  276. asCScriptString *out = AddStringUInt(*str, i);
  277. gen->SetReturnAddress(out);
  278. }
  279. static asCScriptString *AddStringInt(const asCScriptString &str, int i)
  280. {
  281. ostringstream stream;
  282. stream << i;
  283. return new asCScriptString(str.buffer + stream.str());
  284. }
  285. static void AddStringInt_Generic(asIScriptGeneric *gen)
  286. {
  287. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(0);
  288. int i = gen->GetArgDWord(1);
  289. asCScriptString *out = AddStringInt(*str, i);
  290. gen->SetReturnAddress(out);
  291. }
  292. static asCScriptString *AddStringFloat(const asCScriptString &str, float f)
  293. {
  294. ostringstream stream;
  295. stream << f;
  296. return new asCScriptString(str.buffer + stream.str());
  297. }
  298. static void AddStringFloat_Generic(asIScriptGeneric *gen)
  299. {
  300. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(0);
  301. float f = gen->GetArgFloat(1);
  302. asCScriptString *out = AddStringFloat(*str, f);
  303. gen->SetReturnAddress(out);
  304. }
  305. static asCScriptString *AddStringDouble(const asCScriptString &str, double f)
  306. {
  307. ostringstream stream;
  308. stream << f;
  309. return new asCScriptString(str.buffer + stream.str());
  310. }
  311. static void AddStringDouble_Generic(asIScriptGeneric *gen)
  312. {
  313. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(0);
  314. double f = gen->GetArgDouble(1);
  315. asCScriptString *out = AddStringDouble(*str, f);
  316. gen->SetReturnAddress(out);
  317. }
  318. //----------------
  319. // value + string
  320. //----------------
  321. static asCScriptString *AddBitsString(asDWORD i, const asCScriptString &str)
  322. {
  323. ostringstream stream;
  324. stream << hex << i;
  325. return new asCScriptString(stream.str() + str.buffer);
  326. }
  327. static void AddBitsString_Generic(asIScriptGeneric *gen)
  328. {
  329. asDWORD i = gen->GetArgDWord(0);
  330. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(1);
  331. asCScriptString *out = AddBitsString(i, *str);
  332. gen->SetReturnAddress(out);
  333. }
  334. static asCScriptString *AddIntString(int i, const asCScriptString &str)
  335. {
  336. ostringstream stream;
  337. stream << i;
  338. return new asCScriptString(stream.str() + str.buffer);
  339. }
  340. static void AddIntString_Generic(asIScriptGeneric *gen)
  341. {
  342. int i = gen->GetArgDWord(0);
  343. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(1);
  344. asCScriptString *out = AddIntString(i, *str);
  345. gen->SetReturnAddress(out);
  346. }
  347. static asCScriptString *AddUIntString(unsigned int i, const asCScriptString &str)
  348. {
  349. ostringstream stream;
  350. stream << i;
  351. return new asCScriptString(stream.str() + str.buffer);
  352. }
  353. static void AddUIntString_Generic(asIScriptGeneric *gen)
  354. {
  355. unsigned int i = gen->GetArgDWord(0);
  356. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(1);
  357. asCScriptString *out = AddUIntString(i, *str);
  358. gen->SetReturnAddress(out);
  359. }
  360. static asCScriptString *AddFloatString(float f, const asCScriptString &str)
  361. {
  362. ostringstream stream;
  363. stream << f;
  364. return new asCScriptString(stream.str() + str.buffer);
  365. }
  366. static void AddFloatString_Generic(asIScriptGeneric *gen)
  367. {
  368. float f = gen->GetArgFloat(0);
  369. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(1);
  370. asCScriptString *out = AddFloatString(f, *str);
  371. gen->SetReturnAddress(out);
  372. }
  373. static asCScriptString *AddDoubleString(double f, const asCScriptString &str)
  374. {
  375. ostringstream stream;
  376. stream << f;
  377. return new asCScriptString(stream.str() + str.buffer);
  378. }
  379. static void AddDoubleString_Generic(asIScriptGeneric *gen)
  380. {
  381. double f = gen->GetArgDouble(0);
  382. asCScriptString *str = (asCScriptString*)gen->GetArgAddress(1);
  383. asCScriptString *out = AddDoubleString(f, *str);
  384. gen->SetReturnAddress(out);
  385. }
  386. //----------
  387. // string[]
  388. //----------
  389. static char *StringCharAt(unsigned int i, asCScriptString &str)
  390. {
  391. if( i >= str.buffer.size() )
  392. {
  393. // Set a script exception
  394. asIScriptContext *ctx = asGetActiveContext();
  395. ctx->SetException("Out of range");
  396. // Return a null pointer
  397. return 0;
  398. }
  399. return &str.buffer[i];
  400. }
  401. static void StringCharAt_Generic(asIScriptGeneric *gen)
  402. {
  403. unsigned int i = gen->GetArgDWord(0);
  404. asCScriptString *str = (asCScriptString*)gen->GetObject();
  405. char *ch = StringCharAt(i, *str);
  406. gen->SetReturnAddress(ch);
  407. }
  408. //-----------------------
  409. // AngelScript functions
  410. //-----------------------
  411. // This function allocates memory for the string object
  412. static void *StringAlloc(int)
  413. {
  414. return new char[sizeof(asCScriptString)];
  415. }
  416. // This function deallocates the memory for the string object
  417. static void StringFree(void *p)
  418. {
  419. assert( p );
  420. delete[] (char*)p;
  421. }
  422. // This is the string factory that creates new strings for the script
  423. static asCScriptString *StringFactory(asUINT length, const char *s)
  424. {
  425. // Return a script handle to a new string
  426. return new asCScriptString(s);
  427. }
  428. static void StringFactory_Generic(asIScriptGeneric *gen)
  429. {
  430. asUINT length = gen->GetArgDWord(0);
  431. const char *s = (const char*)gen->GetArgAddress(1);
  432. asCScriptString *str = StringFactory(length, s);
  433. gen->SetReturnAddress(str);
  434. }
  435. // This is a wrapper for the default asCScriptString constructor, since
  436. // it is not possible to take the address of the constructor directly
  437. static void ConstructString(asCScriptString *thisPointer)
  438. {
  439. // Construct the string in the memory received
  440. new(thisPointer) asCScriptString();
  441. }
  442. static void ConstructString_Generic(asIScriptGeneric *gen)
  443. {
  444. asCScriptString *thisPointer = (asCScriptString *)gen->GetObject();
  445. ConstructString(thisPointer);
  446. }
  447. static void StringEqual_Generic(asIScriptGeneric *gen)
  448. {
  449. string *a = (string*)gen->GetArgAddress(0);
  450. string *b = (string*)gen->GetArgAddress(1);
  451. bool r = *a == *b;
  452. gen->SetReturnDWord(r);
  453. }
  454. static void StringNotEqual_Generic(asIScriptGeneric *gen)
  455. {
  456. string *a = (string*)gen->GetArgAddress(0);
  457. string *b = (string*)gen->GetArgAddress(1);
  458. bool r = *a != *b;
  459. gen->SetReturnDWord(r);
  460. }
  461. static void StringLesserOrEqual_Generic(asIScriptGeneric *gen)
  462. {
  463. string *a = (string*)gen->GetArgAddress(0);
  464. string *b = (string*)gen->GetArgAddress(1);
  465. bool r = *a <= *b;
  466. gen->SetReturnDWord(r);
  467. }
  468. static void StringGreaterOrEqual_Generic(asIScriptGeneric *gen)
  469. {
  470. string *a = (string*)gen->GetArgAddress(0);
  471. string *b = (string*)gen->GetArgAddress(1);
  472. bool r = *a >= *b;
  473. gen->SetReturnDWord(r);
  474. }
  475. static void StringLesser_Generic(asIScriptGeneric *gen)
  476. {
  477. string *a = (string*)gen->GetArgAddress(0);
  478. string *b = (string*)gen->GetArgAddress(1);
  479. bool r = *a < *b;
  480. gen->SetReturnDWord(r);
  481. }
  482. static void StringGreater_Generic(asIScriptGeneric *gen)
  483. {
  484. string *a = (string*)gen->GetArgAddress(0);
  485. string *b = (string*)gen->GetArgAddress(1);
  486. bool r = *a > *b;
  487. gen->SetReturnDWord(r);
  488. }
  489. static void StringLength_Generic(asIScriptGeneric *gen)
  490. {
  491. string *s = (string*)gen->GetObject();
  492. size_t l = s->size();
  493. gen->SetReturnDWord((asUINT)l);
  494. }
  495. // This is where we register the string type
  496. void RegisterScriptString_Native(asIScriptEngine *engine)
  497. {
  498. int r;
  499. // Register the type
  500. r = engine->RegisterObjectType("string", sizeof(asCScriptString), asOBJ_CLASS_CDA); assert( r >= 0 );
  501. // Register the object operator overloads
  502. // Note: We don't have to register the destructor, since the object uses reference counting
  503. r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  504. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADDREF, "void f()", asMETHOD(asCScriptString,AddRef), asCALL_THISCALL); assert( r >= 0 );
  505. r = engine->RegisterObjectBehaviour("string", asBEHAVE_RELEASE, "void f()", asMETHOD(asCScriptString,Release), asCALL_THISCALL); assert( r >= 0 );
  506. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(const string &in)", asMETHODPR(asCScriptString, operator =, (const asCScriptString&), asCScriptString&), asCALL_THISCALL); assert( r >= 0 );
  507. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(const string &in)", asMETHODPR(asCScriptString, operator+=, (const asCScriptString&), asCScriptString&), asCALL_THISCALL); assert( r >= 0 );
  508. // Register the memory allocator routines. This will make all memory allocations for the string
  509. // object be made in one place, which is important if for example the script library is used from a dll
  510. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ALLOC, "string &f(uint)", asFUNCTION(StringAlloc), asCALL_CDECL); assert( r >= 0 );
  511. r = engine->RegisterObjectBehaviour("string", asBEHAVE_FREE, "void f(string &in)", asFUNCTION(StringFree), asCALL_CDECL); assert( r >= 0 );
  512. // Register the factory to return a handle to a new string
  513. // Note: We must register the string factory after the basic behaviours,
  514. // otherwise the library will not allow the use of object handles for this type
  515. r = engine->RegisterStringFactory("string@", asFUNCTION(StringFactory), asCALL_CDECL); assert( r >= 0 );
  516. // Register the global operator overloads
  517. // Note: We can use std::string's methods directly because the
  518. // internal std::string is placed at the beginning of the class
  519. r = engine->RegisterGlobalBehaviour(asBEHAVE_EQUAL, "bool f(const string &in, const string &in)", asFUNCTIONPR(operator==, (const string &, const string &), bool), asCALL_CDECL); assert( r >= 0 );
  520. r = engine->RegisterGlobalBehaviour(asBEHAVE_NOTEQUAL, "bool f(const string &in, const string &in)", asFUNCTIONPR(operator!=, (const string &, const string &), bool), asCALL_CDECL); assert( r >= 0 );
  521. r = engine->RegisterGlobalBehaviour(asBEHAVE_LEQUAL, "bool f(const string &in, const string &in)", asFUNCTIONPR(operator<=, (const string &, const string &), bool), asCALL_CDECL); assert( r >= 0 );
  522. r = engine->RegisterGlobalBehaviour(asBEHAVE_GEQUAL, "bool f(const string &in, const string &in)", asFUNCTIONPR(operator>=, (const string &, const string &), bool), asCALL_CDECL); assert( r >= 0 );
  523. r = engine->RegisterGlobalBehaviour(asBEHAVE_LESSTHAN, "bool f(const string &in, const string &in)", asFUNCTIONPR(operator <, (const string &, const string &), bool), asCALL_CDECL); assert( r >= 0 );
  524. r = engine->RegisterGlobalBehaviour(asBEHAVE_GREATERTHAN, "bool f(const string &in, const string &in)", asFUNCTIONPR(operator >, (const string &, const string &), bool), asCALL_CDECL); assert( r >= 0 );
  525. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, const string &in)", asFUNCTIONPR(operator +, (const asCScriptString &, const asCScriptString &), asCScriptString*), asCALL_CDECL); assert( r >= 0 );
  526. // Register the index operator, both as a mutator and as an inspector
  527. r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "uint8 &f(uint)", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  528. r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "const uint8 &f(uint) const", asFUNCTION(StringCharAt), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  529. // Register the object methods
  530. r = engine->RegisterObjectMethod("string", "uint length() const", asMETHOD(string,size), asCALL_THISCALL); assert( r >= 0 );
  531. // Automatic conversion from values
  532. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(double)", asFUNCTION(AssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  533. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(double)", asFUNCTION(AddAssignDoubleToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  534. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, double)", asFUNCTION(AddStringDouble), asCALL_CDECL); assert( r >= 0 );
  535. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(double, const string &in)", asFUNCTION(AddDoubleString), asCALL_CDECL); assert( r >= 0 );
  536. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(float)", asFUNCTION(AssignFloatToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  537. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(float)", asFUNCTION(AddAssignFloatToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  538. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, float)", asFUNCTION(AddStringFloat), asCALL_CDECL); assert( r >= 0 );
  539. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(float, const string &in)", asFUNCTION(AddFloatString), asCALL_CDECL); assert( r >= 0 );
  540. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(int)", asFUNCTION(AssignIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  541. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(int)", asFUNCTION(AddAssignIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  542. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, int)", asFUNCTION(AddStringInt), asCALL_CDECL); assert( r >= 0 );
  543. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(int, const string &in)", asFUNCTION(AddIntString), asCALL_CDECL); assert( r >= 0 );
  544. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(uint)", asFUNCTION(AssignUIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  545. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(uint)", asFUNCTION(AddAssignUIntToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  546. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, uint)", asFUNCTION(AddStringUInt), asCALL_CDECL); assert( r >= 0 );
  547. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(uint, const string &in)", asFUNCTION(AddUIntString), asCALL_CDECL); assert( r >= 0 );
  548. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(bits)", asFUNCTION(AssignBitsToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  549. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(bits)", asFUNCTION(AddAssignBitsToString), asCALL_CDECL_OBJLAST); assert( r >= 0 );
  550. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, bits)", asFUNCTION(AddStringBits), asCALL_CDECL); assert( r >= 0 );
  551. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(bits, const string &in)", asFUNCTION(AddBitsString), asCALL_CDECL); assert( r >= 0 );
  552. }
  553. void RegisterScriptString_Generic(asIScriptEngine *engine)
  554. {
  555. int r;
  556. // Register the type
  557. r = engine->RegisterObjectType("string", sizeof(asCScriptString), asOBJ_CLASS_CDA); assert( r >= 0 );
  558. // Register the object operator overloads
  559. // Note: We don't have to register the destructor, since the object uses reference counting
  560. r = engine->RegisterObjectBehaviour("string", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructString_Generic), asCALL_GENERIC); assert( r >= 0 );
  561. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADDREF, "void f()", asFUNCTION(StringAddRef_Generic), asCALL_GENERIC); assert( r >= 0 );
  562. r = engine->RegisterObjectBehaviour("string", asBEHAVE_RELEASE, "void f()", asFUNCTION(StringRelease_Generic), asCALL_GENERIC); assert( r >= 0 );
  563. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(const string &in)", asFUNCTION(AssignString_Generic), asCALL_GENERIC); assert( r >= 0 );
  564. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(const string &in)", asFUNCTION(AddAssignString_Generic), asCALL_GENERIC); assert( r >= 0 );
  565. // Register the memory allocator routines. This will make all memory allocations for the string
  566. // object be made in one place, which is important if for example the script library is used from a dll
  567. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ALLOC, "string &f(uint)", asFUNCTION(StringAlloc), asCALL_CDECL); assert( r >= 0 );
  568. r = engine->RegisterObjectBehaviour("string", asBEHAVE_FREE, "void f(string &in)", asFUNCTION(StringFree), asCALL_CDECL); assert( r >= 0 );
  569. // Register the factory to return a handle to a new string
  570. // Note: We must register the string factory after the basic behaviours,
  571. // otherwise the library will not allow the use of object handles for this type
  572. r = engine->RegisterStringFactory("string@", asFUNCTION(StringFactory_Generic), asCALL_GENERIC); assert( r >= 0 );
  573. // Register the global operator overloads
  574. // Note: We can use std::string's methods directly because the
  575. // internal std::string is placed at the beginning of the class
  576. r = engine->RegisterGlobalBehaviour(asBEHAVE_EQUAL, "bool f(const string &in, const string &in)", asFUNCTION(StringEqual_Generic), asCALL_GENERIC); assert( r >= 0 );
  577. r = engine->RegisterGlobalBehaviour(asBEHAVE_NOTEQUAL, "bool f(const string &in, const string &in)", asFUNCTION(StringNotEqual_Generic), asCALL_GENERIC); assert( r >= 0 );
  578. r = engine->RegisterGlobalBehaviour(asBEHAVE_LEQUAL, "bool f(const string &in, const string &in)", asFUNCTION(StringLesserOrEqual_Generic), asCALL_GENERIC); assert( r >= 0 );
  579. r = engine->RegisterGlobalBehaviour(asBEHAVE_GEQUAL, "bool f(const string &in, const string &in)", asFUNCTION(StringGreaterOrEqual_Generic), asCALL_GENERIC); assert( r >= 0 );
  580. r = engine->RegisterGlobalBehaviour(asBEHAVE_LESSTHAN, "bool f(const string &in, const string &in)", asFUNCTION(StringLesser_Generic), asCALL_GENERIC); assert( r >= 0 );
  581. r = engine->RegisterGlobalBehaviour(asBEHAVE_GREATERTHAN, "bool f(const string &in, const string &in)", asFUNCTION(StringGreater_Generic), asCALL_GENERIC); assert( r >= 0 );
  582. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, const string &in)", asFUNCTION(ConcatenateStrings_Generic), asCALL_GENERIC); assert( r >= 0 );
  583. // Register the index operator, both as a mutator and as an inspector
  584. r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "uint8 &f(uint)", asFUNCTION(StringCharAt_Generic), asCALL_GENERIC); assert( r >= 0 );
  585. r = engine->RegisterObjectBehaviour("string", asBEHAVE_INDEX, "const uint8 &f(uint) const", asFUNCTION(StringCharAt_Generic), asCALL_GENERIC); assert( r >= 0 );
  586. // Register the object methods
  587. r = engine->RegisterObjectMethod("string", "uint length() const", asFUNCTION(StringLength_Generic), asCALL_GENERIC); assert( r >= 0 );
  588. // Automatic conversion from values
  589. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(double)", asFUNCTION(AssignDoubleToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  590. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(double)", asFUNCTION(AddAssignDoubleToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  591. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, double)", asFUNCTION(AddStringDouble_Generic), asCALL_GENERIC); assert( r >= 0 );
  592. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(double, const string &in)", asFUNCTION(AddDoubleString_Generic), asCALL_GENERIC); assert( r >= 0 );
  593. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(float)", asFUNCTION(AssignFloatToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  594. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(float)", asFUNCTION(AddAssignFloatToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  595. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, float)", asFUNCTION(AddStringFloat_Generic), asCALL_GENERIC); assert( r >= 0 );
  596. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(float, const string &in)", asFUNCTION(AddFloatString_Generic), asCALL_GENERIC); assert( r >= 0 );
  597. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(int)", asFUNCTION(AssignIntToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  598. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(int)", asFUNCTION(AddAssignIntToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  599. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, int)", asFUNCTION(AddStringInt_Generic), asCALL_GENERIC); assert( r >= 0 );
  600. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(int, const string &in)", asFUNCTION(AddIntString_Generic), asCALL_GENERIC); assert( r >= 0 );
  601. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(uint)", asFUNCTION(AssignUIntToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  602. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(uint)", asFUNCTION(AddAssignUIntToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  603. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, uint)", asFUNCTION(AddStringUInt_Generic), asCALL_GENERIC); assert( r >= 0 );
  604. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(uint, const string &in)", asFUNCTION(AddUIntString_Generic), asCALL_GENERIC); assert( r >= 0 );
  605. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ASSIGNMENT, "string &f(bits)", asFUNCTION(AssignBitsToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  606. r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADD_ASSIGN, "string &f(bits)", asFUNCTION(AddAssignBitsToString_Generic), asCALL_GENERIC); assert( r >= 0 );
  607. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(const string &in, bits)", asFUNCTION(AddStringBits_Generic), asCALL_GENERIC); assert( r >= 0 );
  608. r = engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "string@ f(bits, const string &in)", asFUNCTION(AddBitsString_Generic), asCALL_GENERIC); assert( r >= 0 );
  609. }
  610. void RegisterScriptString(asIScriptEngine *engine)
  611. {
  612. if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
  613. RegisterScriptString_Generic(engine);
  614. else
  615. RegisterScriptString_Native(engine);
  616. }
  617. END_AS_NAMESPACE