Misc.h 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /******************************************************************************
  2. Here is a list of miscellaneous helper functions.
  3. /******************************************************************************/
  4. enum ALIGN_TYPE // Align Type
  5. {
  6. ALIGN_NONE , // no align
  7. ALIGN_MIN , // align to minimum
  8. ALIGN_CENTER, // align to center
  9. ALIGN_MAX , // align to maximum
  10. };
  11. #if EE_PRIVATE
  12. enum FADE_TYPE : Byte // Fade Type
  13. {
  14. FADE_NONE, // no fading
  15. FADE_IN , // fading in
  16. FADE_OUT , // fading out
  17. };
  18. #endif
  19. /******************************************************************************/
  20. template<typename TYPE, Int elms> constexpr Int Elms(C TYPE (&Array)[elms]) {return elms;} // get number of elements in array
  21. inline Bool InRange(Int i, Byte elms) {return UInt (i)<UInt (elms);} // if 'i' index is in range "0..elms-1", this assumes that "elms>=0"
  22. inline Bool InRange(Int i, Int elms) {return UInt (i)<UInt (elms);} // if 'i' index is in range "0..elms-1", this assumes that "elms>=0"
  23. inline Bool InRange(Int i, UInt elms) {return UInt (i)<UInt (elms);} // if 'i' index is in range "0..elms-1", this assumes that "elms>=0"
  24. inline Bool InRange(UInt i, Int elms) {return UInt (i)<UInt (elms);} // if 'i' index is in range "0..elms-1", this assumes that "elms>=0"
  25. inline Bool InRange(UInt i, UInt elms) {return UInt (i)<UInt (elms);} // if 'i' index is in range "0..elms-1", this assumes that "elms>=0"
  26. inline Bool InRange(Long i, Long elms) {return ULong(i)<ULong(elms);} // if 'i' index is in range "0..elms-1", this assumes that "elms>=0"
  27. inline Bool InRange(Long i, ULong elms) {return ULong(i)<ULong(elms);} // if 'i' index is in range "0..elms-1", this assumes that "elms>=0"
  28. inline Bool InRange(ULong i, ULong elms) {return ULong(i)<ULong(elms);} // if 'i' index is in range "0..elms-1", this assumes that "elms>=0"
  29. T1(TYPE) ENABLE_IF_ENUM(TYPE, Bool) InRange(Int i, TYPE enum_value) {return UInt(i)<UInt(enum_value);} // template specialization for enum's
  30. T1(TYPE) ENABLE_IF_ENUM(TYPE, Bool) InRange(TYPE i, TYPE enum_value) {return UInt(i)<UInt(enum_value);} // template specialization for enum's
  31. T1(TYPE) DISABLE_IF_ENUM(TYPE, Bool) InRange(Int i, C TYPE &container); // if 'i' index is in range of container, 'container' can be of many types, for example a C++ array (x[]), memory container ('Memc', 'Memb', ..) or any other type for which 'Elms' function was defined
  32. T1(TYPE) DISABLE_IF_ENUM(TYPE, Bool) InRange(UInt i, C TYPE &container); // if 'i' index is in range of container, 'container' can be of many types, for example a C++ array (x[]), memory container ('Memc', 'Memb', ..) or any other type for which 'Elms' function was defined
  33. T1(TYPE) DISABLE_IF_ENUM(TYPE, Bool) InRange(Long i, C TYPE &container); // if 'i' index is in range of container, 'container' can be of many types, for example a C++ array (x[]), memory container ('Memc', 'Memb', ..) or any other type for which 'Elms' function was defined
  34. T1(TYPE) DISABLE_IF_ENUM(TYPE, Bool) InRange(ULong i, C TYPE &container); // if 'i' index is in range of container, 'container' can be of many types, for example a C++ array (x[]), memory container ('Memc', 'Memb', ..) or any other type for which 'Elms' function was defined
  35. Str GetBase (C Str &name); // get base name , sample usage: GetBase ("C:/Folder/file.ext") -> "file.ext"
  36. Str GetBaseNoExt(C Str &name); // get base name without extension, sample usage: GetBaseNoExt("C:/Folder/file.ext") -> "file"
  37. Str GetExt (C Str &name); // get extension , sample usage: GetExt ("C:/Folder/file.ext") -> "ext"
  38. Str GetExtNot (C Str &name); // get not extension , sample usage: GetExtNot ("C:/Folder/file.ext") -> "C:/Folder/file"
  39. Str GetPath (C Str &name); // get path , sample usage: GetPath ("C:/Folder/file.ext") -> "C:/Folder"
  40. Str GetStart (C Str &name); // get path start , sample usage: GetStart ("C:/Folder/file.ext") -> "C:"
  41. Str GetStartNot (C Str &name); // get not path start , sample usage: GetStartNot ("C:/Folder/file.ext") -> "Folder/file.ext"
  42. Str GetRelativePath(Str src, Str dest); // get relative path from 'src' location to 'dest' file, sample usage: GetRelativePath("C:/Folder", "C:/dest.txt") -> "../dest.txt"
  43. #if EE_PRIVATE
  44. INLINE Bool IsSlash(Char c) {return c=='/' || c=='\\';}
  45. CChar * _GetBase (CChar *name, Bool tail_slash= 0, Char (&dest)[MAX_LONG_PATH]=ConstCast(TempChar <MAX_LONG_PATH>()).c); // 'tail_slash'=if keep tail slash
  46. CChar * _GetBaseNoExt(CChar *name, Char (&dest)[MAX_LONG_PATH]=ConstCast(TempChar <MAX_LONG_PATH>()).c);
  47. CChar * _GetExt (CChar *name, Char (&dest)[MAX_LONG_PATH]=ConstCast(TempChar <MAX_LONG_PATH>()).c);
  48. CChar * _GetExtNot (CChar *name, Char (&dest)[MAX_LONG_PATH]=ConstCast(TempChar <MAX_LONG_PATH>()).c);
  49. CChar * _GetPath (CChar *name, Int tail_slash=-1, Char (&dest)[MAX_LONG_PATH]=ConstCast(TempChar <MAX_LONG_PATH>()).c); // 'tail_slash'=if insert tail slash (1=always, 0=never, -1=if name had a tail slash)
  50. Char8* _GetStart (CChar8 *name, Char8 (&dest)[MAX_LONG_PATH]=ConstCast(TempChar8<MAX_LONG_PATH>()).c);
  51. Char * _GetStart (CChar *name, Char (&dest)[MAX_LONG_PATH]=ConstCast(TempChar <MAX_LONG_PATH>()).c);
  52. CChar * _GetStartNot (CChar *name);
  53. Str WindowsPath (C Str &path); // replace '/' with '\\'
  54. Str UnixPath (C Str &path); // replace '\\' with '/'
  55. Str8 UnixPathUTF8(C Str &path); // return UnixPath in UTF-8 format
  56. #endif
  57. Bool IsDrive (CChar *path); Bool IsDrive (CChar8 *path); // if path is a drive path, sample usage: IsDrive ("x:/" ) -> true, IsDrive("x:/data/0.bmp") -> false, IsDrive("data/0.bmp") -> false
  58. Bool HasDrive (CChar *path); Bool HasDrive (CChar8 *path); // if path contains drive path, sample usage: HasDrive ("x:/" ) -> true, HasDrive("x:/data/0.bmp") -> true , HasDrive("data/0.bmp") -> false
  59. Bool HasRemote(CChar *path); Bool HasRemote(CChar8 *path); // if path contains remote path, sample usage: HasRemote("\\\\comp") -> true
  60. Bool FullPath (CChar *path); Bool FullPath (CChar8 *path); // if path is a full path (has a drive or is remote)
  61. T3(TA,TB,TC) inline TA& Clamp(TA &x, TB min, TC max) {if(x<min)x=min;else if(x>max)x=max; return x;} // clamp 'x' to "min..max" range
  62. T2(TA,TB ) inline Bool FlagTest (TA flags, TB f ) {return (flags&f)!=0;} // check if 'f' flag is enabled in 'flags', in case 'f' contains multiple options then this will succeed if any of them are enabled
  63. T2(TA,TB ) inline Bool FlagAll (TA flags, TB f ) {return (flags&f)==f;} // check if 'f' flag is enabled in 'flags', in case 'f' contains multiple options then this will succeed if all of them are enabled
  64. T2(TA,TB ) inline void FlagEnable (TA &flags, TB f ) {flags|= f;} // enable 'f' flag in 'flags'
  65. T2(TA,TB ) inline void FlagDisable(TA &flags, TB f ) {flags&=~f;} // disable 'f' flag in 'flags'
  66. T2(TA,TB ) inline void FlagToggle (TA &flags, TB f ) {flags^= f;} // toggle 'f' flag in 'flags'
  67. T2(TA,TB ) inline void FlagSet (TA &flags, TB f, Bool on ) {if(on)FlagEnable(flags, f);else FlagDisable(flags, f);} // set 'f' flag to be enabled or disabled in 'flags'
  68. T3(TA,TB,TC) inline void FlagCopy (TA &flags, TB f, TC mask) {flags=(flags&~mask)|(f&mask);} // copy 'f' flags to 'flags' using specified mask
  69. inline UInt IndexToFlag(Int i) {return 1<<i;} // convert index to flag
  70. inline Int DivFloor(Int x, Int y) {return (x>=0) ? x /y : (x-y+1)/y;} // integer divide with floor
  71. inline Long DivFloor(Long x, Long y) {return (x>=0) ? x /y : (x-y+1)/y;} // integer divide with floor
  72. inline UInt DivFloor(UInt x, UInt y) {return x /y ;} // integer divide with floor
  73. inline ULong DivFloor(ULong x, ULong y) {return x /y ;} // integer divide with floor
  74. inline Int DivCeil (Int x, Int y) {return (x<=0) ? x /y : (x+y-1)/y;} // integer divide with ceil
  75. inline Long DivCeil (Long x, Long y) {return (x<=0) ? x /y : (x+y-1)/y;} // integer divide with ceil
  76. inline UInt DivCeil (UInt x, UInt y) {return (x+y-1)/y;} // integer divide with ceil
  77. inline ULong DivCeil (ULong x, ULong y) {return (x+y-1)/y;} // integer divide with ceil
  78. inline Int DivRound(Int x, Int y) {return (x>=0) ? (x+y/2)/y : (x-y/2)/y;} // integer divide with round
  79. inline Long DivRound(Long x, Long y) {return (x>=0) ? (x+y/2)/y : (x-y/2)/y;} // integer divide with round
  80. inline UInt DivRound(UInt x, UInt y) {return (x+y/2)/y ;} // integer divide with round
  81. inline ULong DivRound(ULong x, ULong y) {return (x+y/2)/y ;} // integer divide with round
  82. inline Int Mod(Int x, Int y ) {if(!y)return 0; Int z=x%y; return (z>=0) ? z : z+y;} // safe modulo "x%y" , returns always a positive number between "0..y-1"
  83. inline Long Mod(Long x, Long y ) {if(!y)return 0; Long z=x%y; return (z>=0) ? z : z+y;} // safe modulo "x%y" , returns always a positive number between "0..y-1"
  84. Int MidMod(Int x, Int min, Int max); // safe middle modulo, returns always a number between "min..max"
  85. UInt Ceil2 (UInt x); // rounds 'x' to the nearest multiple of 2 , which is equal or greater than 'x'
  86. UInt Ceil4 (UInt x); // rounds 'x' to the nearest multiple of 4 , which is equal or greater than 'x'
  87. UInt Ceil8 (UInt x); // rounds 'x' to the nearest multiple of 8 , which is equal or greater than 'x'
  88. UInt Ceil16 (UInt x); // rounds 'x' to the nearest multiple of 16 , which is equal or greater than 'x'
  89. UInt Ceil32 (UInt x); // rounds 'x' to the nearest multiple of 32 , which is equal or greater than 'x'
  90. UInt Ceil64 (UInt x); // rounds 'x' to the nearest multiple of 64 , which is equal or greater than 'x'
  91. UInt Ceil128 (UInt x); // rounds 'x' to the nearest multiple of 128, which is equal or greater than 'x'
  92. UInt CeilPow2 (UInt x); // rounds 'x' to the nearest power of 2 , which is equal or greater than 'x'
  93. UInt FloorPow2 (UInt x); // rounds 'x' to the nearest power of 2 , which is equal or smaller than 'x'
  94. UInt NearestPow2(UInt x); // rounds 'x' to the nearest power of 2
  95. Bool IsPow2 (UInt x); // if 'x' is a power of 2
  96. Int BitLo (UInt x); // get index of lowest non-zero bit in 'x' (31 if none)
  97. Int BitLo (ULong x); // get index of lowest non-zero bit in 'x' (63 if none)
  98. Int BitHi (UInt x); // get index of highest non-zero bit in 'x' ( 0 if none)
  99. Int BitHi (ULong x); // get index of highest non-zero bit in 'x' ( 0 if none)
  100. Int ByteHi (UInt x); // get index of highest non-zero byte in 'x' ( 0 if none)
  101. Int ByteHi (ULong x); // get index of highest non-zero byte in 'x' ( 0 if none)
  102. #if EE_PRIVATE
  103. Int Log2Ceil(UInt x); // returns Ceil(Log2(x))
  104. Int Log2Ceil(ULong x); // returns Ceil(Log2(x))
  105. inline Int DivCeil2(UInt x) {return DivCeil(x, 2u);}
  106. inline Int DivCeil4(UInt x) {return DivCeil(x, 4u);}
  107. inline Int DivCeil8(UInt x) {return DivCeil(x, 8u);}
  108. inline UInt CeilGL(UInt x) {return Ceil128(x);} // use 'Ceil128' because of crash when setting/getting data due to internal system memmove which reads ahead
  109. INLINE SByte Signed(Byte x) {return x;}
  110. INLINE Short Signed(UShort x) {return x;}
  111. INLINE Int Signed(UInt x) {return x;}
  112. INLINE Long Signed(ULong x) {return x;}
  113. INLINE Byte Unsigned(Char8 x) {return x;}
  114. INLINE UShort Unsigned(Char x) {return x;}
  115. INLINE Byte Unsigned(SByte x) {return x;}
  116. INLINE UShort Unsigned(Short x) {return x;}
  117. INLINE UInt Unsigned(Int x) {return x;}
  118. INLINE ULong Unsigned(Long x) {return x;}
  119. Byte FltToByteScale (Flt x);
  120. Byte FltToByteScale2(Flt x);
  121. Flt ByteScaleToFlt (Byte x);
  122. Flt ByteScale2ToFlt(Byte x);
  123. Int ByteScaleRes( Int res, Byte byte_scale);
  124. VecI2 ByteScaleRes(C VecI2 &res, Byte byte_scale);
  125. Int ByteScale2Res( Int res, Byte byte_scale);
  126. VecI2 ByteScale2Res(C VecI2 &res, Byte byte_scale);
  127. #endif
  128. UInt Shl(UInt x, Int i); // safe "x<<i", works ok on negative 'i', and 'i' greater than 32
  129. UInt Shr(UInt x, Int i); // safe "x>>i", works ok on negative 'i', and 'i' greater than 32
  130. UInt Rol(UInt x, Int i); // safe "x ROL i" (Rotate Left ), works ok on negative 'i', and 'i' greater than 32
  131. UInt Ror(UInt x, Int i); // safe "x ROR i" (Rotate Right), works ok on negative 'i', and 'i' greater than 32
  132. void LogConsole( Bool on=true); // open a console window which will include all messages that were passed to 'Log' and 'LogN' functions, if 'on' is set to false then the console window will be closed instead of opened, this function does not prevent from outputting messages to the log file, if you wish to output only to the console the please open the console using 'LogConsole' and clear the log file name using "LogName(S);" (this function works only on Windows)
  133. void LogName (C Str &name ); Str LogName(); // set/get name for the log file, default="log.txt" (null on Mobile platforms), specifying an empty file name prevents any writing to the file
  134. void LogDel ( ); // delete the log file
  135. void Log (C Str &text ); // write text to the log (this will output the message to the log file if 'LogName' is specified, and to the console window if it was opened with 'LogConsole')
  136. void LogN (C Str &text=S ); // write text and new-line to the log (this will output the message to the log file if 'LogName' is specified, and to the console window if it was opened with 'LogConsole')
  137. void LogShow (Bool thread_id, Bool date, Bool time, Bool cur_time); // set which additional information should be displayed during logging, 'thread_id'=ID of the thread which is writing to log, 'date'=year-month-day at the moment of the log, 'time'=hour-minute-second at the moment of the log, 'cur_time'=time in seconds obtained using 'Time.curTime()'
  138. Bool ClipSet(C Str &text, Bool fix_new_line=true); // set system clipboard value to 'text', 'fix_new_line'=if replace "\n" characters with "\r\n" which are required in Windows operating system
  139. Str ClipGet( Bool fix_new_line=true); // get system clipboard value , 'fix_new_line'=if remove '\r' characters
  140. enum OS_VER // Operating System Version
  141. {
  142. OS_UNKNOWN,
  143. WINDOWS_UNKNOWN,
  144. WINDOWS_2000,
  145. WINDOWS_XP,
  146. WINDOWS_XP_64,
  147. WINDOWS_VISTA,
  148. WINDOWS_7,
  149. WINDOWS_8,
  150. WINDOWS_10,
  151. WINDOWS_SERVER_2003,
  152. WINDOWS_SERVER_2003_R2,
  153. WINDOWS_SERVER_2008,
  154. WINDOWS_SERVER_2008_R2,
  155. WINDOWS_SERVER_2012,
  156. WINDOWS_SERVER_2012_R2,
  157. WINDOWS_SERVER_2016,
  158. OS_MAC,
  159. OS_LINUX,
  160. ANDROID_UNKNOWN,
  161. ANDROID_GINGERBREAD,
  162. ANDROID_HONEYCOMB,
  163. ANDROID_ICE_CREAM_SANDWICH,
  164. ANDROID_JELLY_BEAN,
  165. ANDROID_KIT_KAT,
  166. ANDROID_LOLLIPOP,
  167. ANDROID_MARSHMALLOW,
  168. ANDROID_NOUGAT,
  169. ANDROID_OREO,
  170. ANDROID_PIE,
  171. OS_IOS,
  172. };
  173. VecI4 OSVerNumber( ); // get Operating System version number
  174. OS_VER OSVer ( ); // get Operating System version
  175. OS_VER OSGroup (OS_VER ver=OSVer()); // get Operating System group, this ignores specific versions and returns just the main groups, such as WINDOWS_UNKNOWN, OS_MAC, OS_LINUX, ANDROID_UNKNOWN, OS_IOS
  176. CChar8* OSName (OS_VER ver=OSVer()); // get Operating System name
  177. Bool OSWindows (OS_VER ver=OSVer()); // if Operating System is Windows
  178. Bool OSMac (OS_VER ver=OSVer()); // if Operating System is Mac
  179. Bool OSLinux (OS_VER ver=OSVer()); // if Operating System is Linux
  180. Bool OSAndroid (OS_VER ver=OSVer()); // if Operating System is Android
  181. Bool OSiOS (OS_VER ver=OSVer()); // if Operating System is iOS
  182. Str OSUserName(Bool short_name=false); // get the user name of currently logged in user in the Operating System (for Android platform this will be the main email address associated with the device, 'GET_ACCOUNTS' permission which is by default enabled, needs to be specified in the "AndroidManifest.xml" file in order to access this value)
  183. Bool Explore(C Str &name, Bool select=false ); // explore selected 'name' location, 'select'=if explore the parent location instead, and inside it select desired element. This function will only open folders, drives, URL links using the System File Explorer or Browser, it will never run any programs. If 'name' points to a file, then its parent folder will be opened and the file will always be selected regardless of 'select', false on fail.
  184. Bool Run (C Str &name, C Str &params=S, Bool hidden=false, Bool as_admin=false); // run selected 'name' command/application/file/folder/drive/URL link, 'as_admin'=if run as administrator, Sample Usage: Run("C:/esenthel.exe"), Run("http://www.esenthel.com"), false on fail
  185. Bool OpenAppSettings(); // open application settings, false on fail, this is used only on iOS and Android, after calling this function the OS will open the Application Settings Screen in the System Settings menu
  186. void JavaScriptRun (CChar8 *code); // execute custom java script command , valid only for WEB platform
  187. void JavaScriptRun (CChar *code); // execute custom java script command , valid only for WEB platform
  188. Int JavaScriptRunI(CChar8 *code); // execute custom java script command and return its result as integer, valid only for WEB platform
  189. Int JavaScriptRunI(CChar *code); // execute custom java script command and return its result as integer, valid only for WEB platform
  190. CChar8* JavaScriptRunS(CChar8 *code); // execute custom java script command and return its result as string , valid only for WEB platform
  191. CChar8* JavaScriptRunS(CChar *code); // execute custom java script command and return its result as string , valid only for WEB platform
  192. Bool CreateShortcut(C Str &file, C Str &shortcut, C Str &desc=S, C Str &icon=S); // create a shortcut to 'file' program, shortcut will be placed in 'shortcut' location, with 'desc' description, 'icon'=custom icon file path (set empty to use default icon), Sample Usage: CreateShortcut("C:/Games/Esenthel/Esenthel.exe", SystemPath(SP_MENU_PROG)+"/Esenthel/Esenthel", "Esenthel - 3D Action RPG");
  193. Bool AssociateFileType(Str extension, Str application_path, Str application_id, Str extension_desc=S, Str custom_icon=S); // associate file type with specified application, 'extension'=file extension, 'application_path'=path to application, 'application_id'=unique string identyfing the application (recommended format is "CompanyNamy.AppName"), 'extension_desc'=description of the extension (can be left empty), 'custom_icon'=path to icon file which will be used as the icon for the files of specified extension (if left empty, icon will be taken from the application), false on fail, Sample Usage: AssociateFileType("dat", "c:/program.exe", "Company.Program", "Data File")
  194. Str NormalizePath(C Str &path); // return normalized path, Sample Usage: NormalizePath("C:/Folder/../test") -> "C:/test"
  195. Str CleanFileName(C Str &name); // removes all characters which are disallowed in file names, these include \ / : * ? " < > |
  196. Str EncodeFileName( CPtr src , Int size); // encode 'src' binary data of 'size' size, into string which can be used as a file name
  197. void EncodeFileName( Str &dest, CPtr src , Int size); // encode 'src' binary data of 'size' size, into 'dest' string which can be used as a file name
  198. Bool DecodeFileName(C Str &src , Ptr dest, Int size); // decode binary data from 'src' string, false on fail
  199. T1(TYPE) Str EncodeFileName( C TYPE &elm) {return EncodeFileName( &elm, SIZE(elm));}
  200. T1(TYPE) void EncodeFileName( Str &dest, C TYPE &elm) {return EncodeFileName(dest, &elm, SIZE(elm));}
  201. T1(TYPE) Bool DecodeFileName(C Str &src , TYPE &elm) {return DecodeFileName(src , &elm, SIZE(elm));}
  202. Bool DecodeFileName(CChar *src , UID &elm); // UID optimized version
  203. inline Bool DecodeFileName(C Str &src , UID &elm) {return DecodeFileName(src(), elm);} // UID optimized version
  204. UID FileNameID(C Str &name); // convert base of 'name' (obtained using 'GetBase') to ID using 'DecodeFileName', 'UIDZero' on fail, this works like "UID id; DecodeFileName(GetBase(name), id); return id;"
  205. Str EncodeRaw( CPtr src , Int size); // encode 'src' binary data of 'size' size, into string, this is the most efficient encoding (2-bytes per character), warning: string may contain '\0' null characters
  206. void EncodeRaw( Str &dest, CPtr src , Int size); // encode 'src' binary data of 'size' size, into 'dest' string, this is the most efficient encoding (2-bytes per character), warning: string may contain '\0' null characters
  207. void EncodeRaw( Str8 &dest, CPtr src , Int size); // encode 'src' binary data of 'size' size, into 'dest' string, this is the most efficient encoding (2-bytes per character), warning: string may contain '\0' null characters
  208. Bool DecodeRaw(C Str &src , Ptr dest, Int size); // decode binary data from 'src' string, this is the most efficient encoding (2-bytes per character), false on fail
  209. Bool DecodeRaw(C Str8 &src , Ptr dest, Int size); // decode binary data from 'src' string, this is the most efficient encoding (2-bytes per character), false on fail
  210. T1(TYPE) Str EncodeRaw( C TYPE &elm) {return EncodeRaw( &elm, SIZE(elm));}
  211. T1(TYPE) void EncodeRaw( Str &dest, C TYPE &elm) {return EncodeRaw(dest, &elm, SIZE(elm));}
  212. T1(TYPE) void EncodeRaw( Str8 &dest, C TYPE &elm) {return EncodeRaw(dest, &elm, SIZE(elm));}
  213. T1(TYPE) Bool DecodeRaw(C Str &src , TYPE &elm) {return DecodeRaw(src , &elm, SIZE(elm));}
  214. T1(TYPE) Bool DecodeRaw(C Str8 &src , TYPE &elm) {return DecodeRaw(src , &elm, SIZE(elm));}
  215. VecI4 FileVersion(C Str &name); // get exe/dll file version, (-1, -1, -1, -1) on fail
  216. Bool ValidEmail (C Str &email); // test if 'email' is in correct email format - "[email protected]"
  217. Bool ValidURL (C Str &url ); // test if 'url' is in correct url format - "http://domain.com"
  218. Bool ValidLicenseKey(C Str &key ); // test if 'key' is in correct license key format - "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"
  219. Str CString(C Str &str); // get string as if it would be stored for the C++ language (preceeding '\' and '"' characters with '\' ), for example: CString("abc"def\ghi" ) -> ("abc\"def\\ghi")
  220. Str XmlString(C Str &str); // get string as if it would be stored for the XML text (replacing & -> &amp; < -> &lt; > -> &gt; ' -> &apos; " -> &quot;), for example: XmlString("abc"def\ghi" ) -> ("abc&quot;def\ghi")
  221. Str DecodeXmlString(C Str &str); // decode string back from the XML text (replacing &amp; -> & &lt; -> < &gt; -> > &apos; -> ' &quot; -> "), for example: DecodeXmlString("abc&quot;def\ghi") -> ("abc"def\ghi")
  222. UID DeviceID (Bool per_user); // get a unique ID of this device, 'per_user'=if generate a different ID depending on which user is logged in
  223. Str DeviceManufacturer(); // get Device Manufacturer , available only on Android and Apple
  224. Str DeviceModel (); // get Device Model , available only on Android
  225. Str8 DeviceSerialNumber(); // get Device Serial Number, available only on Android
  226. ULong AndroidID (); // get Android ID - https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID
  227. Str MicrosoftWindowsStoreLink(C Str &app_id); // return a website link to Microsoft Windows Store page for the specified App ID, 'app_id' example = "9NBLGGH4QC8G"
  228. Str AppleAppStoreLink(C Str &app_id); // return a website link to Apple App Store page for the specified App ID, 'app_id' example = "828638910"
  229. Str GooglePlayStoreLink(C Str &app_id); // return a website link to Google Play Store page for the specified App ID, 'app_id' example = "com.esenthel.dm"
  230. void Break( ); // calling this function will force breakpoint exception, use for debugging
  231. void Exit (C Str &error=S); // immediately exit the application with 'error' message
  232. #if EE_PRIVATE
  233. void ExitNow ( ); // exit now without reporting any messages
  234. void ExitEx (CChar *error=null); // does not require memory allocation for error message, however does not check for call stack
  235. Bool GetCallStack (Str &stack );
  236. Bool GetCallStackFast(Str &stack );
  237. void InitMisc ( );
  238. // display a message box and always return false
  239. Bool Error (C Str &msg );
  240. Bool ErrorDel (C Str &file );
  241. Bool ErrorRead (C Str &file );
  242. Bool ErrorWrite(C Str &file );
  243. Bool ErrorCopy (C Str &src, C Str &dest);
  244. Bool ErrorMove (C Str &src, C Str &dest);
  245. CChar* _EncodeFileName(C UID &id, Char (&name)[24+1]=ConstCast(TempChar<24+1>()).c); // have to use 'CChar' instead of 'CChar8' because this function is passed to _Cache._find,_get,_require
  246. #endif
  247. /******************************************************************************/
  248. struct ExeSection
  249. {
  250. enum TYPE : Byte
  251. {
  252. CONSTANT , // section memory data should always be constant , have the same data in the process memory as in the exe file
  253. CONST_PROCESS, // section memory data should be constant after loading the process, may have different data in the process memory from the exe file
  254. VARIABLE , // section memory data may change
  255. HASH , // section used to store the hash
  256. };
  257. TYPE type;
  258. Char8 name[9];
  259. UInt size;
  260. union
  261. {
  262. UIntPtr offset;
  263. CPtr offset_p;
  264. };
  265. Bool contains(UIntPtr offset)C {return offset>=T.offset && offset<T.offset+T.size;} // check if section contains specified offset
  266. Bool contains( CPtr offset)C {return contains(UIntPtr(offset));} // check if section contains specified offset
  267. };
  268. Bool ParseProcess( MemPtr<ExeSection> sections); // parse current process and list its sections, false on fail
  269. Bool ParseExe ( File &f , MemPtr<ExeSection> sections); // parse EXE file and list its sections, false on fail
  270. Bool ParseExe (C Str &name, MemPtr<ExeSection> sections); // parse EXE file and list its sections, false on fail
  271. Int FindSectionNameI (C MemPtr<ExeSection> &sections, CChar8 *name ); // find section index by its name , -1 on fail
  272. Int FindSectionOffsetI(C MemPtr<ExeSection> &sections, CPtr offset); // find section index by offset it should belong to, -1 on fail
  273. C ExeSection* FindSectionName (C MemPtr<ExeSection> &sections, CChar8 *name ); // find section index by its name , null on fail
  274. C ExeSection* FindSectionOffset (C MemPtr<ExeSection> &sections, CPtr offset); // find section index by offset it should belong to, null on fail
  275. /******************************************************************************/
  276. enum SYSTEM_PATH // System Path Type
  277. {
  278. SP_NONE , // none
  279. SP_DESKTOP , // Desktop (typically "C:/Users/*/Desktop")
  280. SP_PROG_FILES , // Program Files (typically "C:/Program Files")
  281. SP_SYSTEM , // System (typically "C:/Windows/System32")
  282. SP_MENU , // Start Menu (typically "C:/Users/*/AppData/Roaming/Microsoft/Windows/Start Menu")
  283. SP_MENU_PROG , // Start Menu/Programs (typically "C:/Users/*/AppData/Roaming/Microsoft/Windows/Start Menu/Programs")
  284. SP_STARTUP , // Start Menu/Startup (typically "C:/Users/*/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup")
  285. SP_FAVORITES , // User/Favorites (typically "C:/Users/*/Favorites")
  286. SP_ONE_DRIVE , // User/One Drive (typically "C:/Users/*/OneDrive")
  287. SP_DOCUMENTS , // User/Documents (typically "C:/Users/*/Documents" , for Mobile platforms this is the Application's private folder, where it can save its data that no other App can access)
  288. SP_SAVED_GAMES , // User/Saved Games (typically "C:/Users/*/Saved Games" , for Mobile platforms this is the Application's public folder, or if it's not available, then private folder is selected)
  289. SP_APP_DATA , // User/App Data (typically "C:/Users/*/AppData/Roaming", for Mobile platforms this is the Application's private folder, where it can save its data that no other App can access)
  290. SP_APP_DATA_PUBLIC, // User/App Data (typically "C:/Users/*/AppData/Roaming", for Mobile platforms this is the Application's public folder, where it can save its data that other Apps can access)
  291. SP_ALL_APP_DATA , // All Users/App Data (typically "C:/ProgramData")
  292. SP_PUBLIC , // for Android this is the path to the public folder which is visible when connected to a computer
  293. SP_SD_CARD , // for Android this is the path to SD Card
  294. #if EE_PRIVATE
  295. SP_FRAMEWORKS , // User/Frameworks (typically "/Users/*/Library/Frameworks") used only on Mac
  296. SP_TRASH , // User/Trash (typically "/home/*/.local/share/Trash" ) used only on Linux
  297. #endif
  298. };
  299. Str SystemPath(SYSTEM_PATH type); // get system path, Sample Usage: SystemPath(SP_PROG_FILES) -> "C:/Program Files"
  300. Str AndroidExpansionFileName(Int version, Bool main=true); // get Android Expansion File Name, 'version'=app build version associated with the expansion file, 'main'=if this is the main or patch expansion file
  301. /******************************************************************************/
  302. enum PERMISSION // Permissions
  303. {
  304. PERMISSION_EXTERNAL_STORAGE, // allow accessing files outside of application folders
  305. PERMISSION_LOCATION , // allow accessing device location using 'Location*' functions
  306. PERMISSION_SOUND_RECORD , // allow recording sounds using 'SoundRecord'
  307. PERMISSION_USER_NAME , // allow accessing system user name using 'OSUserName'
  308. #if EE_PRIVATE
  309. PERMISSION_NUM , // number of permissions
  310. #endif
  311. };
  312. Bool HasPermission(PERMISSION permission); // check if Application has specified 'permission', this function is only intended for Android, on other platforms it always returns true
  313. void GetPermission(PERMISSION permission); // request specified 'permission', this function is only intended for Android, on other platforms it's always ignored
  314. #if EE_PRIVATE
  315. void RequirePermission(PERMISSION permission); // if(!HasPermission(permission))GetPermission(permission)
  316. #endif
  317. /******************************************************************************/
  318. enum EXTENSION_TYPE // Extension Type
  319. {
  320. EXT_NONE , // none
  321. EXT_TEXT , // text
  322. EXT_IMAGE, // image
  323. EXT_SOUND, // sound
  324. EXT_MESH , // mesh
  325. EXT_VIDEO, // video
  326. };
  327. EXTENSION_TYPE ExtType(C Str &ext); // get extension type from given extension name, Sample Usage : ExtType("bmp") -> EXT_IMAGE
  328. #define SUPPORTED_IMAGE_EXT "bmp|png|jpg|jpeg|webp|tga|tif|tiff|dds|psd|ico|cur|img"
  329. #define SUPPORTED_SOUND_EXT "wav|flac|ogg|opus|weba|webm|mp3|mp4|m4a"
  330. #define SUPPORTED_MESH_EXT "fbx|dae|ase|obj|3ds|b3d|ms3d|psk|mesh"
  331. /******************************************************************************/
  332. enum REG_KEY_GROUP // registry key group
  333. {
  334. RKG_CLASSES_ROOT , // this will be translated to HKEY_CLASSES_ROOT
  335. RKG_CURRENT_USER , // this will be translated to HKEY_CURRENT_USER
  336. RKG_LOCAL_MACHINE, // this will be translated to HKEY_LOCAL_MACHINE
  337. RKG_USERS , // this will be translated to HKEY_USERS
  338. };
  339. enum REG_KEY_TYPE // registry key type
  340. {
  341. REG_KEY_NONE ,
  342. REG_KEY_STRING,
  343. REG_KEY_U32 ,
  344. REG_KEY_U64 ,
  345. REG_KEY_DATA ,
  346. };
  347. REG_KEY_TYPE GetReg (REG_KEY_GROUP reg_key_group, C Str &name, Memc<Byte> *data =null ); // get registry key type and optionally data, REG_KEY_NONE on fail
  348. Str GetRegStr (REG_KEY_GROUP reg_key_group, C Str &name, Bool *success=null ); // get registry key value as String , "" on fail, 'success'=optional parameter which will be set to true if the key exists
  349. UInt GetRegUInt(REG_KEY_GROUP reg_key_group, C Str &name, Bool *success=null ); // get registry key value as UInt , 0 on fail, 'success'=optional parameter which will be set to true if the key exists
  350. Bool SetRegStr (REG_KEY_GROUP reg_key_group, C Str &name, C Str &value ); // set registry key value as String , false on fail
  351. Bool SetRegUInt(REG_KEY_GROUP reg_key_group, C Str &name, UInt value ); // set registry key value as UInt , false on fail
  352. Bool SetRegData(REG_KEY_GROUP reg_key_group, C Str &name, CPtr data, Int size); // set registry key value as binary data , false on fail
  353. #if EE_PRIVATE
  354. #if APPLE
  355. Boolean GetDictionaryBoolean(CFDictionaryRef dict, const void *key);
  356. long GetDictionaryLong (CFDictionaryRef dict, const void *key);
  357. #endif
  358. #endif
  359. /******************************************************************************/
  360. struct CyclicUShort
  361. {
  362. UShort v; // value
  363. Bool operator==(C CyclicUShort &c)C {return v==c.v;}
  364. Bool operator!=(C CyclicUShort &c)C {return v!=c.v;}
  365. Bool operator>=(C CyclicUShort &c)C {return UShort(v-c.v) <USHORT_MAX/2;}
  366. Bool operator> (C CyclicUShort &c)C {return UShort(c.v-v)>=USHORT_MAX/2;}
  367. Bool operator<=(C CyclicUShort &c)C {return UShort(c.v-v)< USHORT_MAX/2;}
  368. Bool operator< (C CyclicUShort &c)C {return UShort(v-c.v)>=USHORT_MAX/2;}
  369. CyclicUShort& operator++( ) {++v; return T;}
  370. void operator++(int) {++v;}
  371. void zero() {v=0;}
  372. CyclicUShort( ) {}
  373. CyclicUShort(UShort v) : v(v) {}
  374. };
  375. struct CyclicUInt
  376. {
  377. UInt v; // value
  378. Bool operator==(C CyclicUInt &c)C {return v==c.v;}
  379. Bool operator!=(C CyclicUInt &c)C {return v!=c.v;}
  380. Bool operator>=(C CyclicUInt &c)C {return UInt(v-c.v) <UINT_MAX/2;}
  381. Bool operator> (C CyclicUInt &c)C {return UInt(c.v-v)>=UINT_MAX/2;}
  382. Bool operator<=(C CyclicUInt &c)C {return UInt(c.v-v)< UINT_MAX/2;}
  383. Bool operator< (C CyclicUInt &c)C {return UInt(v-c.v)>=UINT_MAX/2;}
  384. CyclicUInt& operator++( ) {++v; return T;}
  385. void operator++(int) {++v;}
  386. void zero() {v=0;}
  387. CyclicUInt( ) {}
  388. CyclicUInt(UInt v) : v(v) {}
  389. };
  390. /******************************************************************************/
  391. struct IndexWeight
  392. {
  393. Int index;
  394. Flt weight;
  395. void set(Int index, Flt weight) {T.index=index; T.weight=weight;}
  396. IndexWeight() {}
  397. IndexWeight(Int index, Flt weight) {set(index, weight);}
  398. };
  399. /******************************************************************************/
  400. struct TextPatch
  401. {
  402. enum MODE
  403. {
  404. ADD ,
  405. DEL ,
  406. EQUAL,
  407. };
  408. struct Diff
  409. {
  410. MODE mode;
  411. Str text;
  412. };
  413. Bool ok; // if patch succeeded
  414. Int base_offset, a_offset,
  415. base_length, a_length;
  416. Mems<Diff> diffs;
  417. Int diffLength()C; // get sum of all ADD/DEL Diff text lengths
  418. };
  419. Str Merge(C Str &base, C Str &a, C Str &b, MemPtr<TextPatch> patches=null, Int timeout=-1); // merge 3 texts, 'base'=original text, 'a'=modification of original text, 'b'=another modification of original text, 'patches'=optional paramter that will receive information about patches applied, 'timeout'=approximatelly how long to search for best merge (-1=unlimited), returns merged text
  420. Int Difference(C Str &a, C Str &b); // get number of characters that need to be added/removed to make both strings equal
  421. /******************************************************************************/
  422. T2(BASE, EXTENDED) void ASSERT_BASE_EXTENDED_EX(BASE&, EXTENDED&) {DYNAMIC_ASSERT(static_cast<BASE*>((EXTENDED*)256)==(BASE*)256, "Selected class is not the base class of extended one");}
  423. T2(BASE, EXTENDED) void ASSERT_BASE_EXTENDED_EX(BASE*, EXTENDED*) {DYNAMIC_ASSERT(static_cast<BASE*>((EXTENDED*)256)==(BASE*)256, "Selected class is not the base class of extended one");}
  424. T2(BASE, EXTENDED) void ASSERT_BASE_EXTENDED ( ) {int i=0; ASSERT_BASE_EXTENDED_EX((BASE&)i, (EXTENDED&)i);} // asserts that 'BASE' class is the main base class of 'EXTENDED', this also works for pointers
  425. T1(TYPE) CPtr CType( ) {return (CPtr)&typeid(TYPE);} // convert C++ type into pointer
  426. T1(TYPE) CPtr CType(TYPE &x) {return (CPtr)&typeid(x );} // convert C++ type into pointer
  427. #if EE_PRIVATE
  428. #if WINDOWS
  429. T1(TYPE) Bool IsVirtual( ) {return std::is_polymorphic<TYPE>();}
  430. T1(TYPE) Bool IsVirtual(C TYPE &x) {return std::is_polymorphic<TYPE>();}
  431. #endif
  432. #endif
  433. /******************************************************************************/
  434. enum LANG_TYPE : Byte
  435. {
  436. #ifndef _WINNT_
  437. LANG_NEUTRAL =0x00,
  438. LANG_INVARIANT =0x7F,
  439. LANG_AFRIKAANS =0x36,
  440. LANG_ALBANIAN =0x1C,
  441. LANG_ALSATIAN =0x84,
  442. LANG_AMHARIC =0x5E,
  443. LANG_ARABIC =0x01,
  444. LANG_ARMENIAN =0x2B,
  445. LANG_ASSAMESE =0x4D,
  446. LANG_AZERI =0x2C,
  447. LANG_BASHKIR =0x6D,
  448. LANG_BASQUE =0x2D,
  449. LANG_BELARUSIAN =0x23,
  450. LANG_BENGALI =0x45,
  451. LANG_BRETON =0x7E,
  452. LANG_BOSNIAN =0x1A,
  453. LANG_BULGARIAN =0x02,
  454. LANG_CATALAN =0x03,
  455. LANG_CHINESE =0x04,
  456. LANG_CORSICAN =0x83,
  457. LANG_CROATIAN =0x1A,
  458. LANG_CZECH =0x05,
  459. LANG_DANISH =0x06,
  460. LANG_DARI =0x8C,
  461. LANG_DIVEHI =0x65,
  462. LANG_DUTCH =0x13,
  463. LANG_ENGLISH =0x09,
  464. LANG_ESTONIAN =0x25,
  465. LANG_FAEROESE =0x38,
  466. LANG_FILIPINO =0x64,
  467. LANG_FINNISH =0x0B,
  468. LANG_FRENCH =0x0C,
  469. LANG_FRISIAN =0x62,
  470. LANG_GALICIAN =0x56,
  471. LANG_GEORGIAN =0x37,
  472. LANG_GERMAN =0x07,
  473. LANG_GREEK =0x08,
  474. LANG_GREENLANDIC =0x6F,
  475. LANG_GUJARATI =0x47,
  476. LANG_HAUSA =0x68,
  477. LANG_HEBREW =0x0D,
  478. LANG_HINDI =0x39,
  479. LANG_HUNGARIAN =0x0E,
  480. LANG_ICELANDIC =0x0F,
  481. LANG_IGBO =0x70,
  482. LANG_INDONESIAN =0x21,
  483. LANG_INUKTITUT =0x5D,
  484. LANG_IRISH =0x3C,
  485. LANG_ITALIAN =0x10,
  486. LANG_JAPANESE =0x11,
  487. LANG_KANNADA =0x4B,
  488. LANG_KASHMIRI =0x60,
  489. LANG_KAZAK =0x3F,
  490. LANG_KHMER =0x53,
  491. LANG_KICHE =0x86,
  492. LANG_KINYARWANDA =0x87,
  493. LANG_KONKANI =0x57,
  494. LANG_KOREAN =0x12,
  495. LANG_KYRGYZ =0x40,
  496. LANG_LAO =0x54,
  497. LANG_LATVIAN =0x26,
  498. LANG_LITHUANIAN =0x27,
  499. LANG_LOWER_SORBIAN=0x2E,
  500. LANG_LUXEMBOURGISH=0x6E,
  501. LANG_MACEDONIAN =0x2F,
  502. LANG_MALAY =0x3E,
  503. LANG_MALAYALAM =0x4C,
  504. LANG_MALTESE =0x3A,
  505. LANG_MANIPURI =0x58,
  506. LANG_MAORI =0x81,
  507. LANG_MAPUDUNGUN =0x7A,
  508. LANG_MARATHI =0x4E,
  509. LANG_MOHAWK =0x7C,
  510. LANG_MONGOLIAN =0x50,
  511. LANG_NEPALI =0x61,
  512. LANG_NORWEGIAN =0x14,
  513. LANG_OCCITAN =0x82,
  514. LANG_ORIYA =0x48,
  515. LANG_PASHTO =0x63,
  516. LANG_PERSIAN =0x29,
  517. LANG_POLISH =0x15,
  518. LANG_PORTUGUESE =0x16,
  519. LANG_PUNJABI =0x46,
  520. LANG_QUECHUA =0x6B,
  521. LANG_ROMANIAN =0x18,
  522. LANG_ROMANSH =0x17,
  523. LANG_RUSSIAN =0x19,
  524. LANG_SAMI =0x3B,
  525. LANG_SANSKRIT =0x4F,
  526. LANG_SERBIAN =0x1A,
  527. LANG_SINDHI =0x59,
  528. LANG_SINHALESE =0x5B,
  529. LANG_SLOVAK =0x1B,
  530. LANG_SLOVENIAN =0x24,
  531. LANG_SOTHO =0x6C,
  532. LANG_SPANISH =0x0A,
  533. LANG_SWAHILI =0x41,
  534. LANG_SWEDISH =0x1D,
  535. LANG_SYRIAC =0x5A,
  536. LANG_TAJIK =0x28,
  537. LANG_TAMAZIGHT =0x5F,
  538. LANG_TAMIL =0x49,
  539. LANG_TATAR =0x44,
  540. LANG_TELUGU =0x4A,
  541. LANG_THAI =0x1E,
  542. LANG_TIBETAN =0x51,
  543. LANG_TIGRIGNA =0x73,
  544. LANG_TSWANA =0x32,
  545. LANG_TURKISH =0x1F,
  546. LANG_TURKMEN =0x42,
  547. LANG_UIGHUR =0x80,
  548. LANG_UKRAINIAN =0x22,
  549. LANG_UPPER_SORBIAN=0x2E,
  550. LANG_URDU =0x20,
  551. LANG_UZBEK =0x43,
  552. LANG_VIETNAMESE =0x2A,
  553. LANG_WELSH =0x52,
  554. LANG_WOLOF =0x88,
  555. LANG_XHOSA =0x34,
  556. LANG_YAKUT =0x85,
  557. LANG_YI =0x78,
  558. LANG_YORUBA =0x6A,
  559. LANG_ZULU =0x35,
  560. #endif
  561. LANG_UNKNOWN=LANG_NEUTRAL,
  562. EN=LANG_ENGLISH ,
  563. CN=LANG_CHINESE ,
  564. JP=LANG_JAPANESE ,
  565. KO=LANG_KOREAN ,
  566. DE=LANG_GERMAN ,
  567. FR=LANG_FRENCH ,
  568. PL=LANG_POLISH ,
  569. RU=LANG_RUSSIAN ,
  570. IT=LANG_ITALIAN ,
  571. SP=LANG_SPANISH ,
  572. PO=LANG_PORTUGUESE,
  573. TH=LANG_THAI ,
  574. };
  575. LANG_TYPE OSLanguage ( ); // get Operating System Language
  576. LANG_TYPE LanguageCode ( C Str &lang); // get language from language code
  577. CChar8* LanguageCode (LANG_TYPE lang); // get language code from language
  578. Str LanguageSpecific(LANG_TYPE lang); // get specific alphabet characters for the selected language
  579. /******************************************************************************/
  580. Int Compare(C CyclicUShort &a, C CyclicUShort &b);
  581. Int Compare(C CyclicUInt &a, C CyclicUInt &b);
  582. /******************************************************************************/
  583. struct Notification
  584. {
  585. Ptr user; // user data, default=null
  586. void set(C Str &title, C Str &text, Bool dismissable=true); // set notification parameters, 'dismissable'=if user can dismiss this notification. If this notification already exists, then calling this method will update its properties.
  587. C Str& title ()C {return _title ;} // get title
  588. C Str& text ()C {return _text ;} // get text
  589. Bool dismissable()C {return _dismissable;} // get if dismissable
  590. void hide (); // remove this notification from the status bar
  591. void remove(); // remove this notification from the status bar and 'Notifications' container, after making this call you may no longer operate on this object as it will point to invalid memory
  592. #if !EE_PRIVATE // make constructors private to prevent from manually creating 'Notification' objects as they should be created only through 'Notifications.New'
  593. private:
  594. #endif
  595. Bool _dismissable, _visible;
  596. Str _title, _text;
  597. ~Notification();
  598. Notification();
  599. };
  600. extern Memx<Notification> Notifications; // list of active notifications
  601. #if EE_PRIVATE
  602. void HideNotifications();
  603. #endif
  604. /******************************************************************************/