ProjectLibrary.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Runtime.CompilerServices;
  7. using BansheeEngine;
  8. namespace BansheeEditor
  9. {
  10. /** @addtogroup Library
  11. * @{
  12. */
  13. /// <summary>
  14. /// The primary location for interacting with all the resources in the current project. A complete hierarchy of
  15. /// resources is provided which can be interacted with by importing new ones, deleting them, moving, renaming and similar.
  16. /// </summary>
  17. public sealed class ProjectLibrary : ScriptObject
  18. {
  19. /// <summary>
  20. /// Root entry of the project library, referencing the top level resources folder.
  21. /// </summary>
  22. public static DirectoryEntry Root { get { return Internal_GetRoot(); } }
  23. /// <summary>
  24. /// Absolute path to the current project's project library resource folder.
  25. /// </summary>
  26. public static string ResourceFolder { get { return Internal_GetResourceFolder(); } }
  27. /// <summary>
  28. /// Triggered when a new entry is added to the project library. Provided path relative to the project library
  29. /// resources folder.
  30. /// </summary>
  31. public static event Action<string> OnEntryAdded;
  32. /// <summary>
  33. /// Triggered when an entry is removed from the project library. Provided path relative to the project library
  34. /// resources folder.
  35. /// </summary>
  36. public static event Action<string> OnEntryRemoved;
  37. /// <summary>
  38. /// Triggered when an entry is (re)imported in the project library. Provided path relative to the project library
  39. /// resources folder.
  40. /// </summary>
  41. public static event Action<string> OnEntryImported;
  42. /// <summary>
  43. /// Checks wheher an asset import is currently in progress.
  44. /// </summary>
  45. internal static bool ImportInProgress { get { return importInProgress; } }
  46. private static HashSet<string> queuedForImport = new HashSet<string>();
  47. private static int numImportedFiles;
  48. private static int totalFilesToImport;
  49. private static bool importInProgress;
  50. private const float TIME_SLICE_SECONDS = 0.030f;
  51. /// <summary>
  52. /// Checks the project library folder for any modifications and reimports the required resources.
  53. /// </summary>
  54. /// <param name="synchronous">If true this method will block until the project library has done refreshing,
  55. /// otherwise the refresh will happen over the course of this and next frames.</param>
  56. public static void Refresh(bool synchronous = false)
  57. {
  58. string[] modifiedPaths = Internal_Refresh(ResourceFolder, synchronous);
  59. if (!synchronous)
  60. {
  61. foreach (var modifiedPath in modifiedPaths)
  62. {
  63. if (queuedForImport.Add(modifiedPath))
  64. totalFilesToImport++;
  65. }
  66. }
  67. else
  68. {
  69. foreach (var path in queuedForImport)
  70. Internal_Refresh(path, true);
  71. queuedForImport.Clear();
  72. numImportedFiles = 0;
  73. totalFilesToImport = 0;
  74. }
  75. }
  76. /// <summary>
  77. /// Checks the specified folder for any modifications and reimports the required resources.
  78. /// </summary>
  79. /// <param name="path">Path to a file or folder to refresh. Relative to the project library resources folder or
  80. /// absolute.</param>
  81. public static void Refresh(string path)
  82. {
  83. string[] modifiedPaths = Internal_Refresh(path, false);
  84. foreach (var modifiedPath in modifiedPaths)
  85. {
  86. if (queuedForImport.Add(modifiedPath))
  87. totalFilesToImport++;
  88. }
  89. }
  90. /// <summary>
  91. /// Registers a new resource in the library.
  92. /// </summary>
  93. /// <param name="resource">Resource instance to add to the library. A copy of the resource will be saved at the
  94. /// provided path.</param>
  95. /// <param name="path">Path where where to store the resource. Absolute or relative to the resources folder.</param>
  96. public static void Create(Resource resource, string path)
  97. {
  98. Internal_Create(resource, path);
  99. }
  100. /// <summary>
  101. /// Updates a resource that is already in the library.
  102. /// </summary>
  103. /// <param name="resource">Resource to save.</param>
  104. public static void Save(Resource resource)
  105. {
  106. Internal_Save(resource);
  107. }
  108. /// <summary>
  109. /// Loads a resource from the project library.
  110. /// </summary>
  111. /// <typeparam name="T">Type of the resource to load.</typeparam>
  112. /// <param name="path">Path of the resource to load. Absolute or relative to the resources folder. If a
  113. /// sub-resource within a file is needed, append the name of the subresource to the path (
  114. /// for example mymesh.fbx/my_animation).</param>
  115. /// <returns>Instance of the loaded resource, or null if not found.</returns>
  116. public static T Load<T>(string path) where T : Resource
  117. {
  118. return (T) Internal_Load(path);
  119. }
  120. /// <summary>
  121. /// Triggers a reimport of a resource using the provided import options, if needed.
  122. /// </summary>
  123. /// <param name="path">Path to the resource to reimport, absolute or relative to resources folder.</param>
  124. /// <param name="options">ptional import options to use when importing the resource. Caller must ensure the import
  125. /// options are of the correct type for the resource in question. If null is provided default
  126. /// import options are used.</param>
  127. /// <param name="force">Should the resource be reimported even if no changes are detected.</param>
  128. public static void Reimport(string path, ImportOptions options = null, bool force = false)
  129. {
  130. Internal_Reimport(path, options, force);
  131. }
  132. /// <summary>
  133. /// Checks does the project library contain a file or folder at the specified path.
  134. /// </summary>
  135. /// <param name="path">Path to the file/folder to check, absolute or relative to resources folder.</param>
  136. /// <returns>True if the element exists, false otherwise.</returns>
  137. public static bool Exists(string path)
  138. {
  139. return GetEntry(path) != null;
  140. }
  141. /// <summary>
  142. /// Attempts to locate a library entry that describes a file or a folder in the project library.
  143. /// </summary>
  144. /// <param name="path">Path to the entry to retrieve, absolute or relative to resources folder.</param>
  145. /// <returns>Library entry if found, null otherwise. This object can become invalid on the next library refresh
  146. /// and you are not meant to hold a permanent reference to it.</returns>
  147. public static LibraryEntry GetEntry(string path)
  148. {
  149. return Internal_GetEntry(path);
  150. }
  151. /// <summary>
  152. /// Checks whether the provided path points to a sub-resource. Sub-resource is any resource that is not the
  153. /// primary resource in the file.
  154. /// </summary>
  155. /// <param name="path">Path to the entry, absolute or relative to resources folder.</param>
  156. /// <returns>True if the path is a sub-resource, false otherwise.</returns>
  157. public static bool IsSubresource(string path)
  158. {
  159. return Internal_IsSubresource(path);
  160. }
  161. /// <summary>
  162. /// Attempts to locate meta-data for a resource at the specified path.
  163. /// </summary>
  164. /// <param name="path">Path to the entry to retrieve, absolute or relative to resources folder. If a sub-resource
  165. /// within a file is needed, append the name of the subresource to the path (for example
  166. /// mymesh.fbx/my_animation).</param>
  167. /// <returns>Resource meta-data if the resource was found, null otherwise.</returns>
  168. public static ResourceMeta GetMeta(string path)
  169. {
  170. return Internal_GetMeta(path);
  171. }
  172. /// <summary>
  173. /// Searches the library for a pattern and returns all entries matching it.
  174. /// </summary>
  175. /// <param name="pattern">Pattern to search for. Use wildcard * to match any character(s).</param>
  176. /// <param name="types">Type of resources to search for. If null all entries will be searched.</param>
  177. /// <returns>A set of entries matching the pattern. These objects can become invalid on the next library refresh
  178. /// and you are not meant to hold a permanent reference to them.</returns>
  179. public static LibraryEntry[] Search(string pattern, ResourceType[] types = null)
  180. {
  181. return Internal_Search(pattern, types);
  182. }
  183. /// <summary>
  184. /// Returns a path to a resource stored in the project library.
  185. /// </summary>
  186. /// <param name="resource">Resource to find the path for.</param>
  187. /// <returns>Path to relative to the project library resources folder if resource was found, null otherwise.
  188. /// </returns>
  189. public static string GetPath(Resource resource)
  190. {
  191. return Internal_GetPath(resource);
  192. }
  193. /// <summary>
  194. /// Returns a path to a resource with the specified UUID stored in the project library.
  195. /// </summary>
  196. /// <param name="uuid">Unique identifier of the resources to retrieve the path of.</param>
  197. /// <returns>Path to relative to the project library resources folder if resource was found, null otherwise.
  198. /// </returns>
  199. public static string GetPath(UUID uuid)
  200. {
  201. return Internal_GetPathFromUUID(ref uuid);
  202. }
  203. /// <summary>
  204. /// Deletes a resource in the project library.
  205. /// </summary>
  206. /// <param name="path">Path to the entry to delete, absolute or relative to resources folder.</param>
  207. public static void Delete(string path)
  208. {
  209. Internal_Delete(path);
  210. }
  211. /// <summary>
  212. /// Creates a new folder in the library.
  213. /// </summary>
  214. /// <param name="path">Path of the folder to create. Absolute or relative to the resources folder.</param>
  215. public static void CreateFolder(string path)
  216. {
  217. Internal_CreateFolder(path);
  218. }
  219. /// <summary>
  220. /// Renames an entry in the project library.
  221. /// </summary>
  222. /// <param name="path">Path of the entry to rename, absolute or relative to resources folder.</param>
  223. /// <param name="name">New name of the entry with an extension.</param>
  224. /// <param name="overwrite">Determines should the entry be deleted if one with the provided name already exists. If
  225. /// this is false and an entry already exists, no rename operation will be performed.</param>
  226. public static void Rename(string path, string name, bool overwrite = false)
  227. {
  228. Internal_Rename(path, name, false);
  229. }
  230. /// <summary>
  231. /// Moves an entry in the project library from one path to another.
  232. /// </summary>
  233. /// <param name="oldPath">Source path of the entry, absolute or relative to resources folder.</param>
  234. /// <param name="newPath">Destination path of the entry, absolute or relative to resources folder.</param>
  235. /// <param name="overwrite">Determines should the entry be deleted if one at the destination path already exists. If
  236. /// this is false and an entry already exists, no move operation will be performed.</param>
  237. public static void Move(string oldPath, string newPath, bool overwrite = false)
  238. {
  239. Internal_Move(oldPath, newPath, overwrite);
  240. }
  241. /// <summary>
  242. /// Copies an entry in the project library from one path to another.
  243. /// </summary>
  244. /// <param name="source">Source path of the entry, absolute or relative to resources folder.</param>
  245. /// <param name="destination">Destination path of the entry, absolute or relative to resources folder.</param>
  246. /// <param name="overwrite">Determines should the entry be deleted if one at the destination path already exists. If
  247. /// this is false and an entry already exists, no copy operation will be performed.</param>
  248. public static void Copy(string source, string destination, bool overwrite = false)
  249. {
  250. Internal_Copy(source, destination, overwrite);
  251. }
  252. /// <summary>
  253. /// Controls should a resource be included an a build. All dependant resources will also be included.
  254. /// </summary>
  255. /// <param name="path">Path of the resource to include, absolute or relative to resources folder.</param>
  256. /// <param name="include">True if it should be included, false otherwise.</param>
  257. public static void SetIncludeInBuild(string path, bool include)
  258. {
  259. Internal_SetIncludeInBuild(path, include);
  260. }
  261. /// <summary>
  262. /// Assigns a non-specific editor data object to the resource at the specified path.
  263. /// </summary>
  264. /// <param name="path">Path to the resource to modify, absolute or relative to resources folder.</param>
  265. /// <param name="userData">Data to assign to the resource, which can later be retrieved from the resource's
  266. /// meta-data as needed. </param>
  267. public static void SetEditorData(string path, object userData)
  268. {
  269. Internal_SetEditorData(path, userData);
  270. }
  271. /// <summary>
  272. /// Triggers reimport for queued resource. Should be called once per frame.
  273. /// </summary>
  274. internal static void Update()
  275. {
  276. if (queuedForImport.Count > 0)
  277. {
  278. // Skip first frame to get the progress bar a chance to show up
  279. if (importInProgress)
  280. {
  281. UInt64 start = Time.Precise;
  282. List<string> toRemove = new List<string>();
  283. foreach (var entry in queuedForImport)
  284. {
  285. Internal_Refresh(entry, true);
  286. toRemove.Add(entry);
  287. numImportedFiles++;
  288. UInt64 end = Time.Precise;
  289. UInt64 elapsed = end - start;
  290. float elapsedSeconds = elapsed * Time.MicroToSecond;
  291. if (elapsedSeconds > TIME_SLICE_SECONDS)
  292. break;
  293. }
  294. foreach (var entry in toRemove)
  295. queuedForImport.Remove(entry);
  296. }
  297. if (queuedForImport.Count == 0)
  298. {
  299. numImportedFiles = 0;
  300. totalFilesToImport = 0;
  301. ProgressBar.Hide();
  302. }
  303. else
  304. {
  305. IEnumerator<string> enumerator = queuedForImport.GetEnumerator();
  306. enumerator.MoveNext();
  307. string displayName = enumerator.Current;
  308. displayName = displayName.Replace("\\", "\\\\");
  309. if (displayName.Length > 60)
  310. {
  311. displayName = displayName.Remove(0, displayName.Length - 60);
  312. displayName = "..." + displayName;
  313. }
  314. float pct = numImportedFiles / (float)totalFilesToImport;
  315. ProgressBar.Show("Importing (" + numImportedFiles + "/" + totalFilesToImport + ")", displayName, pct);
  316. }
  317. importInProgress = true;
  318. }
  319. else
  320. importInProgress = false;
  321. }
  322. /// <summary>
  323. /// Triggered internally by the runtime when a new entry is added to the project library.
  324. /// </summary>
  325. /// <param name="path">Path relative to the project library resources folder.</param>
  326. private static void Internal_DoOnEntryAdded(string path)
  327. {
  328. if (OnEntryAdded != null)
  329. OnEntryAdded(path);
  330. }
  331. /// <summary>
  332. /// Triggered internally by the runtime when an entry is removed from the project library.
  333. /// </summary>
  334. /// <param name="path">Path relative to the project library resources folder.</param>
  335. private static void Internal_DoOnEntryRemoved(string path)
  336. {
  337. if (OnEntryRemoved != null)
  338. OnEntryRemoved(path);
  339. }
  340. /// <summary>
  341. /// Triggered internally by the runtime when an entry is (re)imported in the project library.
  342. /// </summary>
  343. /// <param name="path">Path relative to the project library resources folder.</param>
  344. private static void Internal_DoOnEntryImported(string path)
  345. {
  346. if (OnEntryImported != null)
  347. OnEntryImported(path);
  348. }
  349. [MethodImpl(MethodImplOptions.InternalCall)]
  350. private static extern string[] Internal_Refresh(string path, bool import);
  351. [MethodImpl(MethodImplOptions.InternalCall)]
  352. private static extern void Internal_Create(Resource resource, string path);
  353. [MethodImpl(MethodImplOptions.InternalCall)]
  354. private static extern Resource Internal_Load(string path);
  355. [MethodImpl(MethodImplOptions.InternalCall)]
  356. private static extern void Internal_Save(Resource resource);
  357. [MethodImpl(MethodImplOptions.InternalCall)]
  358. private static extern DirectoryEntry Internal_GetRoot();
  359. [MethodImpl(MethodImplOptions.InternalCall)]
  360. private static extern bool Internal_IsSubresource(string path);
  361. [MethodImpl(MethodImplOptions.InternalCall)]
  362. private static extern void Internal_Reimport(string path, ImportOptions options, bool force);
  363. [MethodImpl(MethodImplOptions.InternalCall)]
  364. private static extern LibraryEntry Internal_GetEntry(string path);
  365. [MethodImpl(MethodImplOptions.InternalCall)]
  366. private static extern ResourceMeta Internal_GetMeta(string path);
  367. [MethodImpl(MethodImplOptions.InternalCall)]
  368. private static extern LibraryEntry[] Internal_Search(string path, ResourceType[] types);
  369. [MethodImpl(MethodImplOptions.InternalCall)]
  370. private static extern string Internal_GetPath(Resource resource);
  371. [MethodImpl(MethodImplOptions.InternalCall)]
  372. private static extern string Internal_GetPathFromUUID(ref UUID uuid);
  373. [MethodImpl(MethodImplOptions.InternalCall)]
  374. private static extern void Internal_Delete(string path);
  375. [MethodImpl(MethodImplOptions.InternalCall)]
  376. private static extern void Internal_CreateFolder(string path);
  377. [MethodImpl(MethodImplOptions.InternalCall)]
  378. private static extern void Internal_Rename(string path, string name, bool overwrite);
  379. [MethodImpl(MethodImplOptions.InternalCall)]
  380. private static extern void Internal_Move(string oldPath, string newPath, bool overwrite);
  381. [MethodImpl(MethodImplOptions.InternalCall)]
  382. private static extern void Internal_Copy(string source, string destination, bool overwrite);
  383. [MethodImpl(MethodImplOptions.InternalCall)]
  384. private static extern string Internal_GetResourceFolder();
  385. [MethodImpl(MethodImplOptions.InternalCall)]
  386. private static extern void Internal_SetIncludeInBuild(string path, bool force);
  387. [MethodImpl(MethodImplOptions.InternalCall)]
  388. private static extern void Internal_SetEditorData(string path, object userData);
  389. }
  390. /// <summary>
  391. /// Type of project library entries.
  392. /// </summary>
  393. public enum LibraryEntryType // Note: Must match the C++ enum ProjectLibrary::LibraryEntryType
  394. {
  395. File, Directory
  396. }
  397. /// <summary>
  398. /// Type of resources supported by the project library.
  399. /// </summary>
  400. public enum ResourceType // Note: Must match the C++ enum ScriptResourceType
  401. {
  402. Texture, SpriteTexture, Mesh, Font, Shader, ShaderInclude, Material, Prefab, PlainText,
  403. ScriptCode, StringTable, GUISkin, PhysicsMaterial, PhysicsMesh, AudioClip, AnimationClip, Undefined
  404. }
  405. /// <summary>
  406. /// A generic project library entry that may be a file or a folder.
  407. /// </summary>
  408. public class LibraryEntry : ScriptObject
  409. {
  410. /// <summary>
  411. /// Path of the library entry, relative to the project library resources folder.
  412. /// </summary>
  413. public string Path { get { return Internal_GetPath(mCachedPtr); } }
  414. /// <summary>
  415. /// Name of the library entry.
  416. /// </summary>
  417. public string Name { get { return Internal_GetName(mCachedPtr); } }
  418. /// <summary>
  419. /// Type of the library entry.
  420. /// </summary>
  421. public LibraryEntryType Type { get { return Internal_GetType(mCachedPtr); } }
  422. /// <summary>
  423. /// Directory entry that contains this entry. This may be null for the root entry.
  424. /// </summary>
  425. public DirectoryEntry Parent { get { return Internal_GetParent(mCachedPtr); } }
  426. [MethodImpl(MethodImplOptions.InternalCall)]
  427. private static extern string Internal_GetPath(IntPtr thisPtr);
  428. [MethodImpl(MethodImplOptions.InternalCall)]
  429. private static extern string Internal_GetName(IntPtr thisPtr);
  430. [MethodImpl(MethodImplOptions.InternalCall)]
  431. private static extern LibraryEntryType Internal_GetType(IntPtr thisPtr);
  432. [MethodImpl(MethodImplOptions.InternalCall)]
  433. private static extern DirectoryEntry Internal_GetParent(IntPtr thisPtr);
  434. }
  435. /// <summary>
  436. /// A project library entry representing a directory that contains other entries.
  437. /// </summary>
  438. public class DirectoryEntry : LibraryEntry
  439. {
  440. /// <summary>
  441. /// A set of entries contained in this entry.
  442. /// </summary>
  443. public LibraryEntry[] Children { get { return Internal_GetChildren(mCachedPtr); } }
  444. [MethodImpl(MethodImplOptions.InternalCall)]
  445. private static extern LibraryEntry[] Internal_GetChildren(IntPtr thisPtr);
  446. }
  447. /// <summary>
  448. /// A library entry representing a file.
  449. /// </summary>
  450. public class FileEntry : LibraryEntry
  451. {
  452. /// <summary>
  453. /// Import options used for importing the resources in the file.
  454. /// </summary>
  455. public ImportOptions Options { get { return Internal_GetImportOptions(mCachedPtr); } }
  456. /// <summary>
  457. /// Returns meta-data for all resources part of the file represented by this object.
  458. /// </summary>
  459. public ResourceMeta[] ResourceMetas { get { return Internal_GetResourceMetas(mCachedPtr); } }
  460. /// <summary>
  461. /// Determines will the resources in the file be included in the project build.
  462. /// </summary>
  463. public bool IncludeInBuild { get { return Internal_GetIncludeInBuild(mCachedPtr); } }
  464. [MethodImpl(MethodImplOptions.InternalCall)]
  465. private static extern ImportOptions Internal_GetImportOptions(IntPtr thisPtr);
  466. [MethodImpl(MethodImplOptions.InternalCall)]
  467. private static extern ResourceMeta[] Internal_GetResourceMetas(IntPtr thisPtr);
  468. [MethodImpl(MethodImplOptions.InternalCall)]
  469. private static extern bool Internal_GetIncludeInBuild(IntPtr thisPtr);
  470. }
  471. /// <summary>
  472. /// Contains meta-data for a resource in the ProjectLibrary.
  473. /// </summary>
  474. public class ResourceMeta : ScriptObject
  475. {
  476. /// <summary>
  477. /// Unique identifier of the resource.
  478. /// </summary>
  479. public UUID UUID
  480. {
  481. get
  482. {
  483. UUID uuid;
  484. Internal_GetUUID(mCachedPtr, out uuid);
  485. return uuid;
  486. }
  487. }
  488. /// <summary>
  489. /// Returns a name of the subresources. Each resource within a file has a unique name.
  490. /// </summary>
  491. public string SubresourceName { get { return Internal_GetSubresourceName(mCachedPtr); } }
  492. /// <summary>
  493. /// Custom icon for the resource to display in the editor, if the resource has one.
  494. /// </summary>
  495. public Texture Icon { get { return Internal_GetIcon(mCachedPtr); } }
  496. /// <summary>
  497. /// Type of the resource referenced by this entry.
  498. /// </summary>
  499. public ResourceType ResType { get { return Internal_GetResourceType(mCachedPtr); } }
  500. /// <summary>
  501. /// Non-specific data assigned to the resource, available in editor only.
  502. /// </summary>
  503. public object EditorData { get { return Internal_GetEditorData(mCachedPtr); } }
  504. [MethodImpl(MethodImplOptions.InternalCall)]
  505. private static extern void Internal_GetUUID(IntPtr thisPtr, out UUID uuid);
  506. [MethodImpl(MethodImplOptions.InternalCall)]
  507. private static extern string Internal_GetSubresourceName(IntPtr thisPtr);
  508. [MethodImpl(MethodImplOptions.InternalCall)]
  509. private static extern Texture Internal_GetIcon(IntPtr thisPtr);
  510. [MethodImpl(MethodImplOptions.InternalCall)]
  511. private static extern ResourceType Internal_GetResourceType(IntPtr thisPtr);
  512. [MethodImpl(MethodImplOptions.InternalCall)]
  513. private static extern object Internal_GetEditorData(IntPtr thisPtr);
  514. }
  515. /** @} */
  516. }