|
1 /* |
|
2 * Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 using System; |
|
19 using System.Collections.Generic; |
|
20 using SymbianDebugLib.Entity; |
|
21 using SymbianDebugLib.PluginAPI; |
|
22 using SymbianSymbolLib.SourceManagement.Provisioning; |
|
23 using SymbianSymbolLib.SourceManagement.Source; |
|
24 using SymbianUtils; |
|
25 |
|
26 namespace SymbianSymbolLib.DbgEnginePlugin |
|
27 { |
|
28 internal class SymbolPrimer : DbgPluginPrimer, IEnumerable<SymSource> |
|
29 { |
|
30 #region Constructors |
|
31 public SymbolPrimer( SymbolPlugin aPlugin ) |
|
32 : base( aPlugin ) |
|
33 { |
|
34 // If we've been created then presumably this is the reason... |
|
35 ProvisioningManager.PrepareToCreateSources(); |
|
36 } |
|
37 #endregion |
|
38 |
|
39 #region From DbgPluginPrimer |
|
40 public override void Add( DbgEntity aEntity ) |
|
41 { |
|
42 SymSourceProvider provider = null; |
|
43 // |
|
44 if ( aEntity.FSEntity.IsFile ) |
|
45 { |
|
46 if ( aEntity.Exists && aEntity.FSEntity.IsValid ) |
|
47 { |
|
48 provider = ProvisioningManager.GetProvider( aEntity.FSEntity.FullName ); |
|
49 } |
|
50 // |
|
51 if ( provider != null ) |
|
52 { |
|
53 using ( SymSourceCollection sources = provider.CreateSources( aEntity.FullName ) ) |
|
54 { |
|
55 // Make sure the time to read attribute is setup in alignment with |
|
56 // whether the entity was explicitly added by the user or found implicitly |
|
57 // by scanning. |
|
58 if ( aEntity.WasAddedExplicitly == false ) |
|
59 { |
|
60 foreach ( SymSource source in sources ) |
|
61 { |
|
62 // This means, don't read this source until it is actually |
|
63 // referenced by the client. I.e. until the client activates |
|
64 // a code segment that refers to this |
|
65 source.TimeToRead = SymSource.TTimeToRead.EReadWhenNeeded; |
|
66 } |
|
67 } |
|
68 |
|
69 // Ownership is transferred |
|
70 iSources.AddRange( sources ); |
|
71 sources.Clear(); |
|
72 } |
|
73 } |
|
74 else |
|
75 { |
|
76 throw new NotSupportedException( "Specified file type is not supported" ); |
|
77 } |
|
78 } |
|
79 else |
|
80 { |
|
81 throw new ArgumentException( "SymbianSymbolLib does not support directory entities" ); |
|
82 } |
|
83 } |
|
84 |
|
85 public override void Prime( TSynchronicity aSynchronicity ) |
|
86 { |
|
87 SymbolPlugin plugin = this.Plugin; |
|
88 |
|
89 // Wipe any state ready for new priming attempt |
|
90 base.OnPrepareToPrime(); |
|
91 if ( base.ResetEngineBeforePriming ) |
|
92 { |
|
93 plugin.Clear(); |
|
94 } |
|
95 |
|
96 // Tell the plugin which sources we are reading |
|
97 plugin.StoreSourcesThatWillBePrimed( this ); |
|
98 |
|
99 // Listen to soure events so that we can report progress |
|
100 SourceEventsSubscribe(); |
|
101 |
|
102 // Report the "priming started event" |
|
103 base.ReportEvent( TPrimeEvent.EEventPrimingStarted, null ); |
|
104 |
|
105 // Now we can start the sources running. |
|
106 foreach ( SymSource source in iSources ) |
|
107 { |
|
108 // If the source wants to read it's data immediately, then activated |
|
109 // it right now... |
|
110 if ( source.TimeToRead == SymSource.TTimeToRead.EReadWhenPriming ) |
|
111 { |
|
112 source.Read( aSynchronicity ); |
|
113 } |
|
114 else |
|
115 { |
|
116 // This source will read it's data on it's own terms so skip |
|
117 // it to ensure that we can track when all the other sources |
|
118 // (that do actually read their files now..) are ready. |
|
119 Skip( source ); |
|
120 } |
|
121 } |
|
122 } |
|
123 |
|
124 protected override int Count |
|
125 { |
|
126 get { return iSources.Count; } |
|
127 } |
|
128 #endregion |
|
129 |
|
130 #region API |
|
131 internal void Skip( SymSource aSource ) |
|
132 { |
|
133 System.Diagnostics.Debug.Assert( aSource.TimeToRead == SymSource.TTimeToRead.EReadWhenNeeded ); |
|
134 bool primeCompleted = base.AddToCompleted( aSource ); |
|
135 CheckForCompletion( primeCompleted ); |
|
136 } |
|
137 #endregion |
|
138 |
|
139 #region Properties |
|
140 internal SymbolPlugin Plugin |
|
141 { |
|
142 get { return base.Engine as SymbolPlugin; } |
|
143 } |
|
144 |
|
145 internal SymSourceManager SourceManager |
|
146 { |
|
147 get { return Plugin.SourceManager; } |
|
148 } |
|
149 |
|
150 internal SymSourceProviderManager ProvisioningManager |
|
151 { |
|
152 get { return Plugin.ProvisioningManager; } |
|
153 } |
|
154 #endregion |
|
155 |
|
156 #region Internal methods |
|
157 private void SourceEventsSubscribe() |
|
158 { |
|
159 SourceEventsUnsubscribe(); |
|
160 // |
|
161 foreach ( SymSource source in iSources ) |
|
162 { |
|
163 source.EventHandler += new SymSource.EventHandlerFunction( Source_EventHandler ); |
|
164 } |
|
165 } |
|
166 |
|
167 private void SourceEventsUnsubscribe() |
|
168 { |
|
169 foreach ( SymSource source in iSources ) |
|
170 { |
|
171 source.EventHandler -= new SymSource.EventHandlerFunction( Source_EventHandler ); |
|
172 } |
|
173 } |
|
174 |
|
175 private void Source_EventHandler( SymSource.TEvent aEvent, SymSource aSource, object aData ) |
|
176 { |
|
177 bool primeCompleted = false; |
|
178 |
|
179 // Map source event onto a primer event |
|
180 if ( aEvent == SymSource.TEvent.EReadingProgress ) |
|
181 { |
|
182 base.SaveLatestProgress( aSource, (int) aData ); |
|
183 } |
|
184 |
|
185 // If all sources are complete, then are we also done? |
|
186 if ( aEvent == SymSource.TEvent.EReadingComplete ) |
|
187 { |
|
188 // We don't need to listen to this source anymore |
|
189 aSource.EventHandler -= new SymSource.EventHandlerFunction( Source_EventHandler ); |
|
190 |
|
191 // Source is 100% complete now. |
|
192 base.SaveLatestProgress( aSource, 100 ); |
|
193 |
|
194 // It's complete, so record as such so that we can tell when all the sources |
|
195 // are now ready. |
|
196 primeCompleted = base.AddToCompleted( aSource ); |
|
197 } |
|
198 |
|
199 CheckForCompletion( primeCompleted ); |
|
200 } |
|
201 |
|
202 private void CheckForCompletion( bool aAmIComplete ) |
|
203 { |
|
204 // Report any progress |
|
205 base.ReportProgressIfNeeded( aAmIComplete ); |
|
206 |
|
207 // Tidy up and report completion |
|
208 if ( aAmIComplete ) |
|
209 { |
|
210 base.OnPrimeComplete(); |
|
211 } |
|
212 } |
|
213 #endregion |
|
214 |
|
215 #region From IEnumerable<SymSource> |
|
216 public IEnumerator<SymSource> GetEnumerator() |
|
217 { |
|
218 return iSources.GetEnumerator(); |
|
219 } |
|
220 |
|
221 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
|
222 { |
|
223 return iSources.GetEnumerator(); |
|
224 } |
|
225 #endregion |
|
226 |
|
227 #region Data members |
|
228 private SymSourceCollection iSources = new SymSourceCollection(); |
|
229 #endregion |
|
230 } |
|
231 } |