Merge pull request #1069 from ScudLee/autoplaynextvideo
[vuplus_xbmc] / xbmc / XBApplicationEx.cpp
1 /*
2  *      Copyright (C) 2005-2012 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  */
20
21 #include "system.h"
22 #include "XBApplicationEx.h"
23 #include "utils/log.h"
24 #include "threads/SystemClock.h"
25 #ifdef HAS_PERFORMANCE_SAMPLE
26 #include "utils/PerformanceSample.h"
27 #else
28 #define MEASURE_FUNCTION
29 #endif
30 #include "commons/Exception.h"
31
32 // Put this here for easy enable and disable
33 #ifndef _DEBUG
34 #define XBMC_TRACK_EXCEPTIONS
35 #endif
36
37 CXBApplicationEx::CXBApplicationEx()
38 {
39   // Variables to perform app timing
40   m_bStop = false;
41   m_AppActive = true;
42   m_AppFocused = true;
43   m_ExitCode = EXITCODE_QUIT;
44 }
45
46 CXBApplicationEx::~CXBApplicationEx()
47 {
48 }
49
50 /* Create the app */
51 bool CXBApplicationEx::Create()
52 {
53   // Variables to perform app timing
54   m_bStop = false;
55   m_AppActive = true;
56   m_AppFocused = true;
57   m_ExitCode = EXITCODE_QUIT;
58
59   // Initialize the app's device-dependent objects
60   if (!Initialize())
61   {
62     CLog::Log(LOGERROR, "XBAppEx: Call to Initialize() failed!" );
63     return false;
64   }
65
66   return true;
67 }
68
69 /* Destroy the app */
70 VOID CXBApplicationEx::Destroy()
71 {
72   CLog::Log(LOGNOTICE, "destroy");
73   // Perform app-specific cleanup
74   Cleanup();
75 }
76
77 /* Function that runs the application */
78 INT CXBApplicationEx::Run(bool renderGUI)
79 {
80   CLog::Log(LOGNOTICE, "Running the application..." );
81
82   unsigned int lastFrameTime = 0;
83   unsigned int frameTime = 0;
84   const unsigned int noRenderFrameTime = 15;  // Simulates ~66fps
85
86 #ifdef XBMC_TRACK_EXCEPTIONS
87   BYTE processExceptionCount = 0;
88   BYTE frameMoveExceptionCount = 0;
89   BYTE renderExceptionCount = 0;
90   const BYTE MAX_EXCEPTION_COUNT = 10;
91 #endif
92
93   // Run xbmc
94   while (!m_bStop)
95   {
96 #ifdef HAS_PERFORMANCE_SAMPLE
97     CPerformanceSample sampleLoop("XBApplicationEx-loop");
98 #endif
99     //-----------------------------------------
100     // Animate and render a frame
101     //-----------------------------------------
102 #ifdef XBMC_TRACK_EXCEPTIONS
103     try
104     {
105 #endif
106       lastFrameTime = XbmcThreads::SystemClockMillis();
107       Process();
108       //reset exception count
109 #ifdef XBMC_TRACK_EXCEPTIONS
110       processExceptionCount = 0;
111
112     }
113     catch (const XbmcCommons::UncheckedException &e)
114     {
115       e.LogThrowMessage("CApplication::Process()");
116       processExceptionCount++;
117       //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out
118       if (processExceptionCount > MAX_EXCEPTION_COUNT)
119       {
120         CLog::Log(LOGERROR, "CApplication::Process(), too many exceptions");
121         throw;
122       }
123     }
124     catch (...)
125     {
126       CLog::Log(LOGERROR, "exception in CApplication::Process()");
127       processExceptionCount++;
128       //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out
129       if (processExceptionCount > MAX_EXCEPTION_COUNT)
130       {
131         CLog::Log(LOGERROR, "CApplication::Process(), too many exceptions");
132         throw;
133       }
134     }
135 #endif
136     // Frame move the scene
137 #ifdef XBMC_TRACK_EXCEPTIONS
138     try
139     {
140 #endif
141       if (!m_bStop) FrameMove(true, renderGUI);
142       //reset exception count
143 #ifdef XBMC_TRACK_EXCEPTIONS
144       frameMoveExceptionCount = 0;
145
146     }
147     catch (const XbmcCommons::UncheckedException &e)
148     {
149       e.LogThrowMessage("CApplication::FrameMove()");
150       frameMoveExceptionCount++;
151       //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out
152       if (frameMoveExceptionCount > MAX_EXCEPTION_COUNT)
153       {
154         CLog::Log(LOGERROR, "CApplication::FrameMove(), too many exceptions");
155         throw;
156       }
157     }
158     catch (...)
159     {
160       CLog::Log(LOGERROR, "exception in CApplication::FrameMove()");
161       frameMoveExceptionCount++;
162       //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out
163       if (frameMoveExceptionCount > MAX_EXCEPTION_COUNT)
164       {
165         CLog::Log(LOGERROR, "CApplication::FrameMove(), too many exceptions");
166         throw;
167       }
168     }
169 #endif
170
171     // Render the scene
172 #ifdef XBMC_TRACK_EXCEPTIONS
173     try
174     {
175 #endif
176       if (renderGUI && !m_bStop) Render();
177       else if (!renderGUI)
178       {
179         frameTime = XbmcThreads::SystemClockMillis() - lastFrameTime;
180         if(frameTime < noRenderFrameTime)
181           Sleep(noRenderFrameTime - frameTime);
182       }
183 #ifdef XBMC_TRACK_EXCEPTIONS
184       //reset exception count
185       renderExceptionCount = 0;
186
187     }
188     catch (const XbmcCommons::UncheckedException &e)
189     {
190       e.LogThrowMessage("CApplication::Render()");
191       renderExceptionCount++;
192       //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out
193       if (renderExceptionCount > MAX_EXCEPTION_COUNT)
194       {
195         CLog::Log(LOGERROR, "CApplication::Render(), too many exceptions");
196         throw;
197       }
198     }
199     catch (...)
200     {
201       CLog::Log(LOGERROR, "exception in CApplication::Render()");
202       renderExceptionCount++;
203       //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out
204       if (renderExceptionCount > MAX_EXCEPTION_COUNT)
205       {
206         CLog::Log(LOGERROR, "CApplication::Render(), too many exceptions");
207         throw;
208       }
209     }
210 #endif
211   } // while (!m_bStop)
212   Destroy();
213
214   CLog::Log(LOGNOTICE, "application stopped..." );
215   return m_ExitCode;
216 }