2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../core/juce_StandardHeader.h"
30 #include "juce_Application.h"
31 #include "../events/juce_MessageManager.h"
32 #include "../core/juce_Initialisation.h"
33 #include "../threads/juce_Process.h"
34 #include "../core/juce_PlatformUtilities.h"
35 #include "../text/juce_LocalisedStrings.h"
38 extern void juce_initialiseMacMainMenu();
41 //==============================================================================
42 class AppBroadcastCallback
: public ActionListener
45 AppBroadcastCallback() { MessageManager::getInstance()->registerBroadcastListener (this); }
46 ~AppBroadcastCallback() { MessageManager::getInstance()->deregisterBroadcastListener (this); }
48 void actionListenerCallback (const String
& message
)
50 JUCEApplication
* const app
= JUCEApplication::getInstance();
52 if (app
!= 0 && message
.startsWith (app
->getApplicationName() + "/"))
53 app
->anotherInstanceStarted (message
.substring (app
->getApplicationName().length() + 1));
57 //==============================================================================
58 JUCEApplication::JUCEApplication()
60 stillInitialising (true)
62 jassert (isStandaloneApp() && appInstance
== nullptr);
66 JUCEApplication::~JUCEApplication()
68 if (appLock
!= nullptr)
74 jassert (appInstance
== this);
75 appInstance
= nullptr;
78 JUCEApplication::CreateInstanceFunction
JUCEApplication::createInstance
= 0;
79 JUCEApplication
* JUCEApplication::appInstance
= nullptr;
81 //==============================================================================
82 bool JUCEApplication::moreThanOneInstanceAllowed()
87 void JUCEApplication::anotherInstanceStarted (const String
&)
91 void JUCEApplication::systemRequestedQuit()
96 void JUCEApplication::quit()
98 MessageManager::getInstance()->stopDispatchLoop();
101 void JUCEApplication::setApplicationReturnValue (const int newReturnValue
) noexcept
103 appReturnValue
= newReturnValue
;
106 //==============================================================================
107 void JUCEApplication::unhandledException (const std::exception
*,
114 void JUCEApplication::sendUnhandledException (const std::exception
* const e
,
115 const char* const sourceFile
,
116 const int lineNumber
)
118 if (appInstance
!= nullptr)
119 appInstance
->unhandledException (e
, sourceFile
, lineNumber
);
122 //==============================================================================
123 ApplicationCommandTarget
* JUCEApplication::getNextCommandTarget()
128 void JUCEApplication::getAllCommands (Array
<CommandID
>& commands
)
130 commands
.add (StandardApplicationCommandIDs::quit
);
133 void JUCEApplication::getCommandInfo (const CommandID commandID
, ApplicationCommandInfo
& result
)
135 if (commandID
== StandardApplicationCommandIDs::quit
)
137 result
.setInfo (TRANS("Quit"),
138 TRANS("Quits the application"),
142 result
.defaultKeypresses
.add (KeyPress ('q', ModifierKeys::commandModifier
, 0));
146 bool JUCEApplication::perform (const InvocationInfo
& info
)
148 if (info
.commandID
== StandardApplicationCommandIDs::quit
)
150 systemRequestedQuit();
157 //==============================================================================
158 bool JUCEApplication::initialiseApp (const String
& commandLine
)
160 commandLineParameters
= commandLine
.trim();
163 jassert (appLock
== nullptr); // initialiseApp must only be called once!
165 if (! moreThanOneInstanceAllowed())
167 appLock
= new InterProcessLock ("juceAppLock_" + getApplicationName());
169 if (! appLock
->enter(0))
172 MessageManager::broadcastMessage (getApplicationName() + "/" + commandLineParameters
);
174 DBG ("Another instance is running - quitting...");
180 // let the app do its setting-up..
181 initialise (commandLineParameters
);
184 juce_initialiseMacMainMenu(); // needs to be called after the app object has created, to get its name
188 broadcastCallback
= new AppBroadcastCallback();
191 stillInitialising
= false;
195 int JUCEApplication::shutdownApp()
197 jassert (appInstance
== this);
199 broadcastCallback
= nullptr;
203 // give the app a chance to clean up..
208 return getApplicationReturnValue();
211 // This is called on the Mac and iOS where the OS doesn't allow the stack to unwind on shutdown..
212 void JUCEApplication::appWillTerminateByForce()
215 const ScopedPointer
<JUCEApplication
> app (JUCEApplication::getInstance());
224 //==============================================================================
226 int JUCEApplication::main (const String
& commandLine
)
228 ScopedJuceInitialiser_GUI libraryInitialiser
;
229 jassert (createInstance
!= nullptr);
233 const ScopedPointer
<JUCEApplication
> app (createInstance());
235 if (! app
->initialiseApp (commandLine
))
240 // loop until a quit message is received..
241 MessageManager::getInstance()->runDispatchLoop();
245 returnCode
= app
->shutdownApp();
252 extern int juce_iOSMain (int argc
, const char* argv
[]);
256 extern const char* juce_Argv0
;
259 int JUCEApplication::main (int argc
, const char* argv
[])
264 jassert (createInstance
!= nullptr);
265 juce_Argv0
= argv
[0];
269 return juce_iOSMain (argc
, argv
);
272 for (int i
= 1; i
< argc
; ++i
)
273 cmd
<< argv
[i
] << ' ';
275 return JUCEApplication::main (cmd
);