1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     SceneManager.cpp
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 46365 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "SceneManager.h"
17 #include "SceneFactory.h"
18 
19 //////////////////////////////////////////////////////////////////////////////////////////
20 // Constant definitions
21 //////////////////////////////////////////////////////////////////////////////////////////
22 
23 namespace
24 {
25     enum SceneState
26     {
27         SCENE_STATE_INITIALIZE = 0, // Initializing
28         SCENE_STATE_UPDATE     = 1, // Updating
29         SCENE_STATE_FINALIZE   = 2, // Finalizing
30 
31         SCENE_STATE_MAX
32     };
33 }
34 
35 //////////////////////////////////////////////////////////////////////////////////////////
36 namespace scene
37 {
38 
39 // Constructor.
SceneManager()40 SceneManager::SceneManager()
41 {
42     m_pScene        = NULL;
43     m_pSceneFactory = NULL;
44     m_sceneId       = SCENE_ID_UNDEFINED;
45     m_sceneState    = SCENE_STATE_INITIALIZE;
46 }
47 
48 // Destructor.
~SceneManager()49 SceneManager::~SceneManager()
50 {
51     Finalize();
52 }
53 
54 // Performs initialization.
Initialize(SceneFactory * pSceneFactory,s32 initialSceneId)55 bool SceneManager::Initialize(SceneFactory* pSceneFactory, s32 initialSceneId)
56 {
57     if (!pSceneFactory || initialSceneId == SCENE_ID_UNDEFINED)
58     {
59         return false;
60     }
61 
62     NN_ASSERT(m_pScene == NULL);
63 
64     // Generate the scene.
65     m_pScene = pSceneFactory->Generate(initialSceneId);
66 
67     if (m_pScene)
68     {
69         m_pSceneFactory = pSceneFactory;
70         m_sceneId       = initialSceneId;
71         m_sceneState    = SCENE_STATE_INITIALIZE;
72     }
73 
74     // Insert SCENE_ID_UNDEFINED in the stack for shutdown determination
75     m_sceneStack.push(SCENE_ID_UNDEFINED);
76 
77     return (m_pScene != NULL);
78 }
79 
80 // Finalizes.
Finalize()81 void SceneManager::Finalize()
82 {
83     if (m_pScene)
84     {
85         m_pScene->Finalize();
86         delete m_pScene;
87     }
88 
89     m_pScene     = NULL;
90     m_sceneId    = SCENE_ID_UNDEFINED;
91     m_sceneState = SCENE_STATE_INITIALIZE;
92 }
93 
94 // Perform update processing.
Update()95 void SceneManager::Update()
96 {
97     if (!m_pScene)
98     {
99         return;
100     }
101 
102     switch (m_sceneState)
103     {
104     case SCENE_STATE_INITIALIZE:
105         {
106             if (m_pScene->Initialize())
107             {
108                 m_sceneState = SCENE_STATE_UPDATE;
109             }
110             else
111             {
112                 Finalize();
113             }
114         }
115         break;
116     case SCENE_STATE_UPDATE:
117         {
118             m_pScene->Update();
119 
120             if (m_pScene->GetNextSceneId() != SCENE_ID_UNDEFINED)
121             {
122                 m_sceneState = SCENE_STATE_FINALIZE;
123             }
124         }
125         break;
126     case SCENE_STATE_FINALIZE:
127         {
128             // Next scene
129             s32 nextSceneId = m_pScene->GetNextSceneId();
130             if(m_pScene->WillSaveSceneIdToStack()){
131                 m_sceneStack.push(m_sceneId);
132                 NN_LOG("Scene depth: %d\n", m_sceneStack.size());
133             }
134 
135             Finalize();
136 
137             if(nextSceneId == SCENE_ID_POP){
138                 NN_ASSERT(m_sceneStack.empty()==false);
139                 nextSceneId=m_sceneStack.top();
140                 m_sceneStack.pop();
141                 NN_LOG("Scene depth: %d\n", m_sceneStack.size());
142             }
143             if (nextSceneId != SCENE_ID_UNDEFINED)
144             {
145                 // Generate the scene.
146                 m_pScene = m_pSceneFactory->Generate(nextSceneId);
147 
148                 if (m_pScene)
149                 {
150                     m_sceneId = nextSceneId;
151                 }
152             }
153         }
154         break;
155     }
156 }
157 
158 // Performs rendering.
Draw()159 void SceneManager::Draw()
160 {
161     if (!m_pScene || m_sceneState != SCENE_STATE_UPDATE)
162     {
163         return;
164     }
165     m_pScene->Draw();
166 }
167 
168 // Get whether to terminate.
IsExpectedToFinish()169 bool SceneManager::IsExpectedToFinish()
170 {
171     return (m_pScene == NULL);
172 }
IsRejectHome()173 bool SceneManager::IsRejectHome()
174 {
175     return (m_pScene == NULL) ? false : m_pScene->IsRejectHome();
176 }
177 
178 } // namespace scene
179 
180