Browse Source

Projucer various fixes

* Use separate folder for disk cache in debug mode to avoid mixing debug/release-mode object files while testing
* Quote the server's file name as it may contain spaces etc.
* Fix saving source files during compilation on Windows
* Fix JuceDemo for live builds on Mac: long chains of recursive operator<< invocations caused compiler crash
* Move code for creating disabled Build tab to extra function and add names to improve readability
* Implement new "subscribe" behavior for createDisabledBuildTab
* Clean up trailing spaces
tags/2021-05-28
stefan 9 years ago
parent
commit
8ec9443543
10 changed files with 152 additions and 66 deletions
  1. +12
    -4
      examples/Demo/Source/Demos/SystemInfoDemo.cpp
  2. +7
    -1
      extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp
  3. +1
    -1
      extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineServer.cpp
  4. +87
    -59
      extras/Projucer/Source/Project/jucer_ProjectContentComponent.cpp
  5. +2
    -0
      extras/Projucer/Source/Project/jucer_ProjectContentComponent.h
  6. +15
    -0
      modules/juce_core/files/juce_File.cpp
  7. +13
    -0
      modules/juce_core/files/juce_File.h
  8. +1
    -1
      modules/juce_core/files/juce_TemporaryFile.cpp
  9. +5
    -0
      modules/juce_core/native/juce_posix_SharedCode.h
  10. +9
    -0
      modules/juce_core/native/juce_win32_Files.cpp

+ 12
- 4
examples/Demo/Source/Demos/SystemInfoDemo.cpp View File

@@ -119,7 +119,9 @@ static String getAllSystemInfo()
<< "User region: " << SystemStats::getUserRegion() << newLine
<< "User language: " << SystemStats::getUserLanguage() << newLine
<< "Display language: " << SystemStats::getDisplayLanguage() << newLine
<< newLine
<< newLine;
systemInfo
<< "Number of CPUs: " << SystemStats::getNumCpus() << newLine
<< "Memory size: " << SystemStats::getMemorySizeInMegabytes() << " MB" << newLine
<< "CPU vendor: " << SystemStats::getCpuVendor() << newLine
@@ -134,12 +136,16 @@ static String getAllSystemInfo()
<< "CPU has 3DNOW: " << (SystemStats::has3DNow() ? "yes" : "no") << newLine
<< "CPU has AVX: " << (SystemStats::hasAVX() ? "yes" : "no") << newLine
<< "CPU has AVX2: " << (SystemStats::hasAVX2() ? "yes" : "no") << newLine
<< newLine
<< newLine;
systemInfo
<< "Current working directory: " << File::getCurrentWorkingDirectory().getFullPathName() << newLine
<< "Current application file: " << File::getSpecialLocation (File::currentApplicationFile).getFullPathName() << newLine
<< "Current executable file: " << File::getSpecialLocation (File::currentExecutableFile) .getFullPathName() << newLine
<< "Invoked executable file: " << File::getSpecialLocation (File::invokedExecutableFile) .getFullPathName() << newLine
<< newLine
<< newLine;
systemInfo
<< "User home folder: " << File::getSpecialLocation (File::userHomeDirectory) .getFullPathName() << newLine
<< "User desktop folder: " << File::getSpecialLocation (File::userDesktopDirectory) .getFullPathName() << newLine
<< "User documents folder: " << File::getSpecialLocation (File::userDocumentsDirectory) .getFullPathName() << newLine
@@ -150,7 +156,9 @@ static String getAllSystemInfo()
<< "Common application data folder: " << File::getSpecialLocation (File::commonApplicationDataDirectory).getFullPathName() << newLine
<< "Common documents folder: " << File::getSpecialLocation (File::commonDocumentsDirectory) .getFullPathName() << newLine
<< "Local temp folder: " << File::getSpecialLocation (File::tempDirectory) .getFullPathName() << newLine
<< newLine
<< newLine;
systemInfo
<< "File System roots: " << getFileSystemRoots() << newLine
<< "Free space in home folder: " << File::descriptionOfSizeInBytes (File::getSpecialLocation (File::userHomeDirectory)
.getBytesFreeOnVolume()) << newLine


+ 7
- 1
extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp View File

@@ -89,9 +89,15 @@ namespace ProjectProperties
static File getCacheLocation (Project& project)
{
String cacheFolderName = project.getProjectFilenameRoot() + "_" + project.getProjectUID();
#if JUCE_DEBUG
cacheFolderName += "_debug";
#endif
return getProjucerTempFolder()
.getChildFile ("Intermediate Files")
.getChildFile (project.getProjectFilenameRoot() + "_" + project.getProjectUID());
.getChildFile (cacheFolderName);
}
}


+ 1
- 1
extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineServer.cpp View File

@@ -230,7 +230,7 @@ String createCommandLineForLaunchingServer (const String& pipeName, const String
const File exe (File::getSpecialLocation (File::currentExecutableFile).getFullPathName());
return exe.getFullPathName() + " " + commandPrefix + info.joinIntoString (commandTokenSeparator);
return "\"" + exe.getFullPathName() + "\" " + commandPrefix + info.joinIntoString (commandTokenSeparator);
}
static ServerIPC* currentServer = nullptr;


+ 87
- 59
extras/Projucer/Source/Project/jucer_ProjectContentComponent.cpp View File

@@ -354,65 +354,95 @@ struct BuildTabComponent : public ConcertinaPanel
struct ProjucerDisabledComp : public Component,
private Button::Listener
{
ProjucerDisabledComp (String message, bool loggedIn, bool canLogin, bool requirePurchase = false,
const String& loginName = String())
: isLoggedIn (loggedIn), isPurchaseButton (requirePurchase)
ProjucerDisabledComp (String message, bool loggedIn, bool showSubscribeButton,
bool showSignInButton, bool showSwitchAccountButton)
: isLoggedIn (loggedIn)
{
infoLabel.setColour (Label::textColourId, findColour (mainBackgroundColourId).contrasting (0.7f));
infoLabel.setJustificationType (Justification::centred);
infoLabel.setText (message, dontSendNotification);
addAndMakeVisible (infoLabel);
if (canLogin)
if (showSubscribeButton)
{
addAndMakeVisible (loginButton);
loginButton.addListener (this);
subscribeButton = new TextButton (String ( "Subscribe..."));
addAndMakeVisible (*subscribeButton);
subscribeButton->addListener (this);
}
if (isPurchaseButton)
{
loginButton.setButtonText ("Purchase JUCE Pro...");
signOutButton = new TextButton (String ("Sign Out ") + loginName);
addAndMakeVisible (*signOutButton);
signOutButton->addListener (this);
}
if (showSignInButton)
{
signInButton = new TextButton (String ( "Sign in..."));
addAndMakeVisible (*signInButton);
signInButton->addListener (this);
}
if (showSwitchAccountButton)
{
switchAccountButton = new TextButton (String ("Switch account..."));
addAndMakeVisible (*switchAccountButton);
switchAccountButton->addListener (this);
}
}
void resized() override
{
infoLabel.centreWithSize (proportionOfWidth (0.9f), 200);
loginButton.setSize (jmin (getWidth() - 10, 150), 22);
loginButton.setCentrePosition (infoLabel.getBounds().getCentreX(),
infoLabel.getBottom() + loginButton.getHeight() * 2);
int infoWidth = proportionOfWidth (0.9f);
int infoHeight = 100;
infoLabel.centreWithSize (infoWidth, infoHeight);
if (signOutButton != nullptr)
int buttonWidth = jmin (getWidth() - 10, 150);
int buttonHeight = 22;
int itemDistance = 10;
int buttonCenterX = infoLabel.getBounds().getCentreX();
int buttonCenterY = infoLabel.getBottom() + itemDistance + buttonHeight / 2;
if (subscribeButton.get() != nullptr)
{
signOutButton->setSize (jmin (getWidth() - 10, 150), 22);
signOutButton->setCentrePosition (infoLabel.getBounds().getCentreX(),
loginButton.getBottom() + 20);
subscribeButton->setSize (buttonWidth, buttonHeight);
subscribeButton->setCentrePosition (buttonCenterX, buttonCenterY);
buttonCenterY += itemDistance + buttonHeight;
}
if (signInButton.get() != nullptr)
{
signInButton->setSize (buttonWidth, buttonHeight);
signInButton->setCentrePosition (buttonCenterX, buttonCenterY);
buttonCenterY += itemDistance + buttonHeight;
}
if (switchAccountButton.get() != nullptr)
{
switchAccountButton->setSize (buttonWidth, buttonHeight);
switchAccountButton->setCentrePosition (buttonCenterX, buttonCenterY);
}
}
void buttonClicked (Button* btn) override
{
if (btn == &loginButton)
if (btn == subscribeButton.get())
{
URL ("http://www.juce.com/get-juce").launchInDefaultBrowser();
}
else if (btn == signInButton.get())
{
if (isPurchaseButton)
URL ("http://www.juce.com").launchInDefaultBrowser();
else
ProjucerApplication::getApp().showLoginForm();
ProjucerApplication::getApp().showLoginForm();
}
else if (btn == signOutButton.get())
else if (btn == switchAccountButton.get())
{
ProjucerLicenses::getInstance()->logout();
ProjucerApplication::getApp().updateAllBuildTabs();
ProjucerApplication::getApp().showLoginForm();
}
}
bool isLoggedIn;
private:
Label infoLabel { "info", String() };
TextButton loginButton { "Log-in..." };
ScopedPointer<TextButton> signOutButton;
bool isLoggedIn, isPurchaseButton;
ScopedPointer<TextButton> subscribeButton;
ScopedPointer<TextButton> signInButton;
ScopedPointer<TextButton> switchAccountButton;
};
struct EnableBuildComp : public Component
@@ -458,33 +488,30 @@ Component* ProjectContentComponent::createBuildTab (CompileEngineChildProcess* c
return new BuildTabComponent (child, new ProjucerAppClasses::ErrorListComp (child->errorList));
}
auto& unlockStatus = *ProjucerLicenses::getInstance();
if (unlockStatus.hasLiveCodingLicence()
&& project != nullptr
&& LiveBuildProjectSettings::isBuildDisabled (*project))
return new EnableBuildComp();
if (unlockStatus.isLoggedIn())
return new ProjucerDisabledComp (String ("The Projucer's live-build features are currently disabled!") + newLine
+ newLine
+ "Your account " + unlockStatus.getLoginName().quoted()
+ " does not have an asscociated JUCE Pro license:",
true, true, true, unlockStatus.getLoginName());
if (! unlockStatus.isDLLPresent())
return new ProjucerDisabledComp (String ("The live-building DLL is missing!") + newLine
+ newLine
+ "To enable the compiler, you'll need to install the missing DLL "
+ CompileEngineDLL::getDLLName().quoted() + newLine
+ newLine
+ "Visit the JUCE website/forum for more help on getting and installing the DLL!",
false, false);
return new ProjucerDisabledComp ("The Projucer's live-build features are currently disabled!\n\n"
"To enable them, you'll need to log-in with your JUCE account details:",
false, true, false);
jassert (project != nullptr);
const auto& unlockStatus = *ProjucerLicenses::getInstance();
if (unlockStatus.hasLiveCodingLicence())
{
jassert (unlockStatus.isLoggedIn());
jassert (unlockStatus.isDLLPresent());
return new EnableBuildComp();
}
return createDisabledBuildTab(unlockStatus.isLoggedIn(),
unlockStatus.isDLLPresent());
#endif
};
//==============================================================================
Component* ProjectContentComponent::createDisabledBuildTab(bool loggedIn, bool dllPresent) {
bool showSubscribeButton = true;
bool showSignInButton = dllPresent && ! loggedIn;
bool showSwitchAccountButton = dllPresent && loggedIn;
return new ProjucerDisabledComp (
"Subscribe to JUCE Pro or Indie to use the Projucer's live-build features:",
loggedIn, showSubscribeButton, showSignInButton, showSwitchAccountButton);
}
BuildTabComponent* findBuildTab (const TabbedComponent& tabs)
@@ -1499,7 +1526,8 @@ void ProjectContentComponent::handleMissingSystemHeaders()
deleteProjectTabs();
createProjectTabs();
ProjucerDisabledComp* buildTab = new ProjucerDisabledComp (tabMessage, false, false);
bool isLoggedIn = ProjucerLicenses::getInstance()->isLoggedIn();
ProjucerDisabledComp* buildTab = new ProjucerDisabledComp (tabMessage, isLoggedIn, false, false, false);
treeViewTabs.addTab ("Build", Colours::transparentBlack, buildTab, true);
showBuildTab();


+ 2
- 0
extras/Projucer/Source/Project/jucer_ProjectContentComponent.h View File

@@ -154,6 +154,8 @@ private:
void timerCallback() override;
Component* createBuildTab (CompileEngineChildProcess*);
Component* createDisabledBuildTab (bool loggedIn, bool dllPresent);
bool isContinuousRebuildEnabled() { return getAppSettings().getGlobalProperties().getBoolValue ("continuousRebuild", true); }
void setContinuousRebuildEnabled (bool b) { getAppSettings().getGlobalProperties().setValue ("continuousRebuild", b); }
void rebuildNow();


+ 15
- 0
modules/juce_core/files/juce_File.cpp View File

@@ -300,6 +300,21 @@ bool File::copyFileTo (const File& newFile) const
|| (exists() && newFile.deleteFile() && copyInternal (newFile));
}
bool File::replaceFileIn (const File& newFile) const
{
if (newFile.fullPath == fullPath)
return true;
if (! newFile.exists())
return moveFileTo (newFile);
if (! replaceInternal (newFile))
return false;
deleteFile();
return true;
}
bool File::copyDirectoryTo (const File& newDirectory) const
{
if (isDirectory() && newDirectory.createDirectory())


+ 13
- 0
modules/juce_core/files/juce_File.h View File

@@ -503,6 +503,18 @@ public:
*/
bool copyFileTo (const File& targetLocation) const;
/** Replaces a file.
Replace the file in the given location, assuming the replaced files identity.
Depending on the file system this will preserve file attributes such as
creation date, short file name, etc.
If replacement succeeds the original file is deleted.
@returns true if the operation succeeds
*/
bool replaceFileIn (const File& targetLocation) const;
/** Copies a directory.
Tries to copy an entire directory, recursively.
@@ -982,6 +994,7 @@ private:
Result createDirectoryInternal (const String&) const;
bool copyInternal (const File&) const;
bool moveInternal (const File&) const;
bool replaceInternal (const File&) const;
bool setFileTimesInternal (int64 m, int64 a, int64 c) const;
void getFileTimesInternal (int64& m, int64& a, int64& c) const;
bool setFileReadOnlyInternal (bool) const;


+ 1
- 1
modules/juce_core/files/juce_TemporaryFile.cpp View File

@@ -86,7 +86,7 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const
// Have a few attempts at overwriting the file before giving up..
for (int i = 5; --i >= 0;)
{
if (temporaryFile.moveFileTo (targetFile))
if (temporaryFile.replaceFileIn (targetFile))
return true;
Thread::sleep (100);


+ 5
- 0
modules/juce_core/native/juce_posix_SharedCode.h View File

@@ -440,6 +440,11 @@ bool File::moveInternal (const File& dest) const
return false;
}
bool File::replaceInternal (const File& dest) const
{
return moveInternal (dest);
}
Result File::createDirectoryInternal (const String& fileName) const
{
return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777));


+ 9
- 0
modules/juce_core/native/juce_win32_Files.cpp View File

@@ -220,6 +220,15 @@ bool File::moveInternal (const File& dest) const
return MoveFile (fullPath.toWideCharPointer(), dest.getFullPathName().toWideCharPointer()) != 0;
}
bool File::replaceInternal (const File& dest) const
{
void* lpExclude = 0;
void* lpReserved = 0;
return ReplaceFile (dest.getFullPathName().toWideCharPointer(), fullPath.toWideCharPointer(),
0, REPLACEFILE_IGNORE_MERGE_ERRORS, lpExclude, lpReserved) != 0;
}
Result File::createDirectoryInternal (const String& fileName) const
{
return CreateDirectory (fileName.toWideCharPointer(), 0) ? Result::ok()


Loading…
Cancel
Save