The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
5.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #include "projucer_LiveCodeBuilderDLL.h"
  20. struct CompileEngineDLL : DeletedAtShutdown
  21. {
  22. CompileEngineDLL()
  23. {
  24. tryLoadDll();
  25. }
  26. ~CompileEngineDLL()
  27. {
  28. shutdown();
  29. }
  30. bool tryLoadDll()
  31. {
  32. // never load the dynamic lib multiple times
  33. if (! isLoaded())
  34. {
  35. auto f = findDLLFile();
  36. if (f != File() && dll.open (f.getLinkedTarget().getFullPathName()))
  37. {
  38. #define INIT_LIVE_DLL_FN(name, returnType, params) name = (name##_type) dll.getFunction (#name);
  39. LIVE_DLL_FUNCTIONS (INIT_LIVE_DLL_FN);
  40. #undef INIT_LIVE_DLL_FN
  41. return true;
  42. }
  43. return false;
  44. }
  45. return true;
  46. }
  47. void initialise (CrashCallbackFunction crashFn, QuitCallbackFunction quitFn, bool setupSignals)
  48. {
  49. if (isLoaded())
  50. projucer_initialise (crashFn, quitFn, setPropertyCallback, getPropertyCallback, setupSignals);
  51. }
  52. void shutdown()
  53. {
  54. if (isLoaded())
  55. projucer_shutdown();
  56. }
  57. bool isLoaded() const
  58. {
  59. #define CHECK_LIVE_DLL_FN(name, returnType, params) if (name == nullptr) return false;
  60. LIVE_DLL_FUNCTIONS (CHECK_LIVE_DLL_FN);
  61. #undef CHECK_LIVE_DLL_FN
  62. return projucer_getVersion() == requiredVersion;
  63. }
  64. #define DECLARE_LIVE_DLL_FN(name, returnType, params) \
  65. typedef returnType (*name##_type) params; \
  66. name##_type name = nullptr;
  67. LIVE_DLL_FUNCTIONS (DECLARE_LIVE_DLL_FN)
  68. #undef DECLARE_LIVE_DLL_FN
  69. static String getDLLName()
  70. {
  71. #if JUCE_MAC
  72. return "JUCECompileEngine.dylib";
  73. #elif JUCE_LINUX
  74. return "JUCECompileEngine.so";
  75. #elif JUCE_WINDOWS
  76. return "JUCECompileEngine.dll";
  77. #else
  78. #error
  79. return "JUCECompileEngine.so";
  80. #endif
  81. }
  82. static File getVersionedUserAppSupportFolder()
  83. {
  84. auto userAppData = File::getSpecialLocation (File::userApplicationDataDirectory);
  85. #if JUCE_MAC
  86. userAppData = userAppData.getChildFile ("Application Support");
  87. #endif
  88. return userAppData.getChildFile ("Projucer").getChildFile (String ("CompileEngine-") + ProjectInfo::versionString);
  89. }
  90. juce_DeclareSingleton (CompileEngineDLL, false)
  91. private:
  92. DynamicLibrary dll;
  93. enum { requiredVersion = 2 };
  94. static File findDLLFile()
  95. {
  96. auto dllFile = File();
  97. if (tryFindDLLFileInAppFolder (dllFile))
  98. return dllFile;
  99. #if JUCE_MAC
  100. if (tryFindDLLFileInAppBundle(dllFile))
  101. return dllFile;
  102. #endif
  103. if (tryFindDLLFileInAppConfigFolder (dllFile))
  104. return dllFile;
  105. return {};
  106. }
  107. #if JUCE_MAC
  108. static bool tryFindDLLFileInAppBundle(File &outFile)
  109. {
  110. File currentAppFile (File::getSpecialLocation (File::currentApplicationFile));
  111. return tryFindDLLFileInFolder (currentAppFile.getChildFile ("Contents"), outFile);
  112. }
  113. #endif
  114. static bool tryFindDLLFileInAppFolder(File &outFile)
  115. {
  116. auto currentAppFile = File::getSpecialLocation (File::currentApplicationFile);
  117. return tryFindDLLFileInFolder (currentAppFile.getParentDirectory(), outFile);
  118. }
  119. static bool tryFindDLLFileInAppConfigFolder(File &outFile)
  120. {
  121. auto userAppDataFolder = getVersionedUserAppSupportFolder();
  122. return tryFindDLLFileInFolder (userAppDataFolder, outFile);
  123. }
  124. static bool tryFindDLLFileInFolder(File folder, File& outFile)
  125. {
  126. auto file = folder.getChildFile (getDLLName());
  127. if (isDLLFile (file))
  128. {
  129. outFile = file;
  130. return true;
  131. }
  132. return false;
  133. }
  134. static bool isDLLFile (const File& f)
  135. {
  136. return f.getFileName().equalsIgnoreCase (getDLLName()) && f.exists();
  137. }
  138. static void setPropertyCallback (const char* key, const char* value)
  139. {
  140. auto keyStr = String (key);
  141. if (keyStr.isNotEmpty())
  142. getGlobalProperties().setValue (key, value);
  143. else
  144. jassertfalse;
  145. }
  146. static void getPropertyCallback (const char* key, char* value, size_t size)
  147. {
  148. jassert (getGlobalProperties().getValue (key).getNumBytesAsUTF8() < size);
  149. value[0] = 0;
  150. getGlobalProperties().getValue (key).copyToUTF8 (value, size);
  151. }
  152. static void crashCallback (const char*) {}
  153. static void quitCallback() {}
  154. };