• R/O
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

FreeTrainの進化系を目指す


Commit MetaInfo

Revision4 (tree)
Time2013-11-10 17:45:07
Authorc477

Log Message

Refactoring around pluginManager.
Pluginのロード方法、一覧ダイアログなど修正.

Change Summary

Incremental Difference

--- framework/framework/Main.cs (revision 3)
+++ framework/framework/Main.cs (revision 4)
@@ -33,7 +33,7 @@
3333 public static readonly NftProperties resources = NftProperties.LoadFromFile(Directories.AppBaseDir + "nftfw.resource.xml", false);
3434
3535 /// <summary> Plug-ins. </summary>
36- public static readonly PluginManager plugins = new PluginManager();
36+ public static readonly PluginManager pluginManager = new PluginManager();
3737
3838 #region sound and BGM
3939 /*
@@ -89,7 +89,7 @@
8989 // load global modules;
9090 GlobalModules.Initialize();
9191 // load plug-ins
92- Main.plugins.init(new string[]{Directories.PluginDir}, monitor);
92+ Main.pluginManager.init(new string[]{Directories.PluginDir}, monitor);
9393 }
9494
9595 //new PluginListDialog().ShowDialog();
--- framework/framework/plugin/Contribution.cs (revision 3)
+++ framework/framework/plugin/Contribution.cs (revision 4)
@@ -220,12 +220,18 @@
220220 /// </summary>
221221 public virtual Assembly Assembly { get { return this.GetType().Assembly; } }
222222
223+ public bool IsPrimitive {
224+ get {
225+ return IsPrimitiveContribution(this.GetType());
226+ }
227+ }
228+
223229 /// <summary>
224230 /// return true if specified class has 'PrimitiveContribution' Attribute.
225231 /// </summary>
226232 /// <param name="type"></param>
227233 /// <returns></returns>
228- public static bool isPrimitiveContribution(Type type) {
234+ public static bool IsPrimitiveContribution(Type type) {
229235 object[] o = type.GetCustomAttributes(typeof(PrimitiveContributionAttribute),true);
230236 return (o != null && o.Length > 0);
231237 }
@@ -267,7 +273,7 @@
267273 internal sealed class ReferenceImpl : IObjectReference {
268274 private string id=null;
269275 public object GetRealObject(StreamingContext context) {
270- object o = Main.plugins.GetContribution(id);
276+ object o = PluginManager.theInstance.GetContribution(id);
271277 if(o==null)
272278 throw new SerializationException(
273279 "コントリビューション\""+id+"\"を含むプラグインが見つかりません");
--- framework/framework/plugin/PluginManager.cs (revision 3)
+++ framework/framework/plugin/PluginManager.cs (revision 4)
@@ -1,5 +1,6 @@
11 using System;
22 using System.Collections;
3+using System.Collections.Generic;
34 using System.Diagnostics;
45 using System.IO;
56 using System.Reflection;
@@ -29,24 +30,19 @@
2930 public ParseEventHandler BeforeContributionParse;
3031
3132 /// <summary>
32- /// All loaded plug-ins.
33- /// </summary>
34- private Plugin[] plugins;
35-
36- /// <summary>
3733 /// Plugins keyed by their names.
3834 /// </summary>
39- private readonly Hashtable pluginMap = new Hashtable();
35+ private readonly Dictionary<string, Plugin> pluginMap = new Dictionary<string, Plugin>();
4036
4137 /// <summary>
4238 /// Contribution factories that are used to load contributions.
4339 /// </summary>
44- private readonly Hashtable contributionFactories = new Hashtable();
40+ private readonly Dictionary<string, IContributionFactory> contributionFactories = new Dictionary<string, IContributionFactory>();
4541
4642 /// <summary>
4743 /// Contributions keyed by their IDs.
4844 /// </summary>
49- private readonly Hashtable contributionMap = new Hashtable();
45+ private readonly Dictionary<string, Contribution> contributionMap = new Dictionary<string, Contribution>();
5046
5147 /// <summary>
5248 /// Contribution Types keyed by their CtbTypes (string specified a Type of Contribution).
@@ -71,12 +67,12 @@
7167 public void init( ICollection dirs, ProgressMonitor monitor )
7268 {
7369 errCount=0;
74- ArrayList pluginSet=SeekPluginDirectories(dirs,monitor);
70+ IList<Plugin> pluginSet=SeekPluginDirectories(dirs,monitor);
7571
76- SolveDependency(pluginSet, monitor);
77- LoadContributions(monitor);
78- InitContributions(monitor);
79-
72+ Plugin[] plugins = SolveDependency(pluginSet, monitor);
73+ LoadContributions(plugins, monitor);
74+ InitContributions(monitor);
75+ DisposeReaders();
8076 // if( errCount!=0 ) {
8177 // // error during the initialization
8278 // Environment.Exit(errCount);
@@ -91,8 +87,8 @@
9187 }
9288
9389 #region initialization processes
94- private ArrayList SeekPluginDirectories(ICollection directories, ProgressMonitor monitor) {
95- ArrayList pluginSet = new ArrayList();
90+ private IList<Plugin> SeekPluginDirectories(ICollection directories, ProgressMonitor monitor) {
91+ List<Plugin> pluginSet = new List<Plugin>();
9692 monitor.Progress(1, 1, "プラグインを検索中");
9793 string[][] subdirs = new string[directories.Count][];
9894 int n = 0;
@@ -110,7 +106,7 @@
110106 }
111107 return pluginSet;
112108 }
113- private void ProcessSubDirectories(ArrayList pluginSet, string parent, string[] subdirs, ProgressMonitor monitor)
109+ private void ProcessSubDirectories(IList<Plugin> pluginSet, string parent, string[] subdirs, ProgressMonitor monitor)
114110 {
115111 foreach( string dir in subdirs )
116112 {
@@ -130,7 +126,7 @@
130126 ParamsReader reader = new ParamsReader(path, parser);
131127 pluginSet.Add( p );
132128 p.LoadParams(reader["plug-in"]);
133- if( pluginMap.Contains(p.ID) )
129+ if( pluginMap.ContainsKey(p.ID) )
134130 {
135131 p._state = InstallationState.FatalError;
136132 // loaded more than once
@@ -137,7 +133,7 @@
137133 // maybe same subdir name in different plugin dirs.
138134 throw new Exception( string.Format(
139135 "プラグイン「{0}」は{1}と{2}の二箇所からロードされています",
140- p.ID, p.Uri, ((Plugin)pluginMap[p.ID]).Uri) );
136+ p.ID, p.Uri, (pluginMap[p.ID]).Uri) );
141137 }
142138 pluginMap.Add( p.ID, p );
143139 }
@@ -154,31 +150,45 @@
154150 }
155151 }
156152
157- private void SolveDependency(ArrayList pluginSet, ProgressMonitor monitor)
153+ private Plugin[] SolveDependency(IList<Plugin> pluginSet, ProgressMonitor monitor)
158154 {// convert it to an array by sorting them in the order of dependency
159155 monitor.Progress(1,1,"依存関係を整理中");
160156 monitor.SetMaximum(2,pluginSet.Count);
161157
162- this.plugins = new Plugin[pluginSet.Count];
158+ Plugin[] plugins = new Plugin[pluginSet.Count];
163159 int ptr=0;
164-
160+
161+ // Add system default plugin to the order-list at first.
162+ Plugin p = GetPlugin("system");
163+ monitor.Progress(2, 1, p.ID);
164+ plugins[ptr++] = p;
165+ pluginSet.Remove(p);
166+ // Loop until pluginSet becomes empty.
165167 while( pluginSet.Count>0 )
166168 {
167- Plugin p = (Plugin)pluginSet[0];
169+ p = pluginSet[0];
168170 monitor.Progress(2,1,p.ID);
169171 try
170172 {
171- while(true)
173+ Plugin pr;
174+ while(true)
172175 {
173- Plugin[] deps = p.getDependencies();
174- int i;
175- for( i=0; i<deps.Length; i++ )
176- if( pluginSet.Contains(deps[i]) )
177- break;
178- if(i==deps.Length)
179- break;
180- else
181- p = deps[i];
176+ List<Plugin> deps = GetDependencies(p, p._reader);
177+ pr = null;
178+ // Pick a dependent plugin from remaining-list (if exist).
179+ foreach (Plugin p2 in deps) {
180+ if (pluginSet.Contains(p2)) {
181+ pr = p2;
182+ break;
183+ }
184+ }
185+ if (pr == null) {
186+ // exit inner while loop to add current 'p' to the orde-list.
187+ break;
188+ } else {
189+ // 'pr' is the one to load earlier, so check dependency of 'pr' next.
190+ p = pr;
191+ }
182192 }
183193 }
184194 catch( Exception e )
@@ -185,13 +195,14 @@
185195 {
186196 ReportError(e.Message,e);
187197 }
188-
198+ // Add 'p' to order-list and remove from remaining-list
189199 pluginSet.Remove(p);
190200 plugins[ptr++] = p;
191201 }
202+ return plugins;
192203 }
193204
194- private void LoadContributions(ProgressMonitor monitor)
205+ private void LoadContributions(Plugin[] plugins, ProgressMonitor monitor)
195206 {
196207 // load all the contributions
197208 monitor.Progress(1,1,"コントリビューションをロード中");
@@ -202,7 +213,7 @@
202213 monitor.Progress(2,1,p.ID);
203214 try
204215 {
205- p.loadBinaries();
216+ LoadBinaries(p, p._reader);
206217 }
207218 catch( Exception e )
208219 {
@@ -216,9 +227,8 @@
216227 try
217228 {
218229 // this will call AddContribution method
219- p.loadContributions();
220- p._state = InstallationState.Ready;
221- }
230+ LoadContributions(p, p._reader);
231+ }
222232 catch( Exception e )
223233 {
224234 p._state = InstallationState.FatalError;
@@ -229,13 +239,16 @@
229239
230240 private void InitContributions(ProgressMonitor monitor)
231241 {
232- // initialize contributions
233242 monitor.Progress(1,1,"コントリビューションを初期化中");
234- Contribution[] arrprm = PrimitiveContributions;
235- Contribution[] arrctb = Contributions;
236- monitor.SetMaximum(2, arrctb.Length+arrprm.Length);
243+ IList nonPrimitives = new List<Contribution>(contributionMap.Count);
244+ monitor.SetMaximum(2, contributionMap.Count);
237245 Hashtable handlers = new Hashtable();
238- foreach (Contribution contrib in arrprm) {
246+ // Initialize all primitive contirbutions before Non primitive contributions.
247+ foreach (Contribution contrib in contributionMap.Values) {
248+ if(!contrib.IsPrimitive){
249+ nonPrimitives.Add(contrib);
250+ continue;
251+ }
239252 try {
240253 InitCompleteEventHandler h = contrib.Initialize();
241254 if (h != null) {
@@ -251,7 +264,7 @@
251264 ReportError(string.Format(templ, contrib.Parent.ID, "contrib.name", contrib.ID), e);
252265 }
253266 }
254- foreach (Contribution contrib in arrctb)
267+ foreach (Contribution contrib in nonPrimitives)
255268 {
256269 try
257270 {
@@ -286,6 +299,16 @@
286299 }
287300 }
288301
302+ private void DisposeReaders() {
303+ foreach (Plugin p in pluginMap.Values) {
304+ IDisposable pr = p._reader as IDisposable;
305+ p._reader = null;
306+ if (pr!=null) {
307+ pr.Dispose();
308+ }
309+ }
310+ }
311+
289312 internal void ReportError(string msg, Exception e)
290313 {
291314 errCount++;
@@ -311,7 +334,129 @@
311334 return Directories.PluginDir;
312335 }
313336
314- #region called from Plugin constructor
337+ #region Loading contributions for eacn Plugins.
338+ /// <summary>
339+ /// Get all the dependent plug-ins.
340+ /// called from PluginManager before initialize this plugin.
341+ /// </summary>
342+ public List<Plugin> GetDependencies(Plugin p, ParamsReader _reader) {
343+ List<Plugin> a = new List<Plugin>();
344+ foreach (ParamsReader depend in _reader.EnumChildren("depend")) {
345+ string name = depend["on"].InnerText;
346+ Plugin p2 = GetPlugin(name);
347+ if (p2 == null) {
348+ string templ = Main.resources["plugin.dependency_not_found"].stringValue;
349+ throw new Exception(String.Format(templ, p.ID, name));
350+ }
351+ a.Add(p2);
352+ }
353+ return a;
354+ }
355+
356+ /// <summary>
357+ /// Loads class type contributions from this plug-in
358+ /// </summary>
359+ internal void LoadBinaries(Plugin p, ParamsReader _reader) {
360+ // locate contribution factories first,
361+ // because we'll need them to load contributions.
362+ foreach (ParamsReader ctb_reader in _reader.EnumChildren("contribution")) {
363+ string type = ctb_reader["type"].InnerText;
364+ try {
365+ Contribution cb = null;
366+ // load a contribution factory
367+ if ("factory".Equals(type)) {
368+ NotifyStartParse(p, ctb_reader);
369+ ParamsReader nd = ctb_reader["declare"];
370+ string regtype;
371+ if (!nd.IsNull) {
372+ regtype = nd["type"].InnerText;
373+ } else {
374+ // use name property for alternative.
375+ regtype = ctb_reader["name"].InnerText;
376+ }
377+ object[] args = new object[] { ctb_reader };
378+ // create and register contribution factory
379+ IContributionFactory factory =
380+ PluginUtil.createCtbFactory(p, ctb_reader);
381+ AddContributionFactory(regtype, factory);
382+ cb = factory as Contribution;
383+ // Register dummy contribution (in order to list on Dialog).
384+ if (cb == null) {
385+ cb = new CtbContributionDefiner(p, ctb_reader);
386+ }
387+ } else if ("binary".Equals(type)) {
388+ NotifyStartParse(p, ctb_reader);
389+ cb = PluginUtil.createContributionObject(p, ctb_reader) as BinaryModule;
390+ if (cb == null) {
391+ // create dummy module for list Dialog
392+ cb = new BinaryModule(p, ctb_reader);
393+ }
394+ } else {
395+ continue;
396+ }
397+ cb.Attach();
398+ cb._state = InstallationState.Ready;
399+ } catch (Exception e) {
400+ p._state = InstallationState.FatalError;
401+ string msg = MakeContribExceptionMessage(p, ctb_reader);
402+ throw new Exception(msg, e);
403+ }
404+ }
405+ }
406+
407+ /// <summary>
408+ /// Loads contributions from this plug-in
409+ /// </summary>
410+ internal void LoadContributions(Plugin p, ParamsReader _reader) {
411+ Contribution c = null;
412+ int count = 0;
413+ int errors = 0;
414+ // load contributions
415+ foreach (ParamsReader ctb_reader in _reader.EnumChildren("contribution")) {
416+ try {
417+ count++;
418+ string type = ctb_reader["type"].InnerText;
419+ if ("factory".Equals(type) || "binary".Equals(type)) continue; // ignore
420+
421+ NotifyStartParse(p, ctb_reader);
422+ IContributionFactory factory = GetContributionFactory(type);
423+ c = factory.load(p, ctb_reader);
424+ c.Attach();
425+ if (c.IsDetachable) {
426+ p.AssociateAddableContribution(c);
427+ }
428+ AddContribution(c);
429+ c._state = InstallationState.Ready;
430+ } catch (Exception e) {
431+ errors++;
432+ Debug.WriteLine(e.Message);
433+ Debug.WriteLine(e.StackTrace);
434+ if (e.InnerException != null) {
435+ Debug.WriteLine(e.InnerException.Message);
436+ Debug.WriteLine(e.InnerException.StackTrace);
437+ }
438+ if (c != null)
439+ c._state = InstallationState.FatalError;
440+ string msg = MakeContribExceptionMessage(p, ctb_reader);
441+ if (p._state != InstallationState.FatalError)
442+ p._state = InstallationState.PartialError;
443+ ReportError(msg, e);
444+ }
445+ }
446+ if (p._state != InstallationState.FatalError && errors == count) {
447+ p._state = InstallationState.FatalError;
448+ } else if (p._state == InstallationState.Uninitialized) {
449+ p._state = InstallationState.Ready;
450+ }
451+ }
452+
453+ private string MakeContribExceptionMessage(Plugin p, ParamsReader pr) {
454+ string templ = Main.resources["plugin.contrib_load_error"].stringValue;
455+ string _id = pr["id"].InnerTextOr("unknown");
456+ string _name = pr["name"].InnerTextOr("unknown");
457+ return string.Format(templ, p.Uri.AbsoluteUri, _name, _id);
458+ }
459+
315460 /// <summary>
316461 /// Registers a <c>ContributionFactory</c>.
317462 /// This method has to be called before the initialization.
@@ -320,7 +465,7 @@
320465 /// </summary>
321466 public void AddContributionFactory( string name, IContributionFactory factory )
322467 {
323- if( contributionFactories.Contains(name) )
468+ if( contributionFactories.ContainsKey(name) )
324469 throw new Exception(string.Format(
325470 "contribution type \"{0}\" is already registered.",name));
326471
@@ -329,8 +474,7 @@
329474
330475 //
331476 public IContributionFactory GetContributionFactory( string name ) {
332- IContributionFactory factory = (IContributionFactory)
333- contributionFactories[name];
477+ IContributionFactory factory = contributionFactories[name];
334478 if(factory==null)
335479 throw new Exception(name+"は未知のコントリビューションです");
336480 else
@@ -341,43 +485,41 @@
341485 /// <summary>
342486 /// Lists up contributions of the given type.
343487 /// </summary>
488+ [Obsolete("Use EnumContributions")]
344489 public Array ListContributions( Type contributionType, bool hideDisabled )
345490 {
346491 ArrayList list = new ArrayList();
347- foreach( Plugin p in plugins ) {
348- foreach( Contribution contrib in p.Contributions ) {
349- if( contributionType.IsInstanceOfType(contrib) )
350- if( !hideDisabled || contrib.IsAttached )
351- list.Add(contrib);
352- }
492+ foreach( Contribution contrib in contributionMap.Values) {
493+ if( contributionType.IsInstanceOfType(contrib) )
494+ if( !hideDisabled || contrib.IsAttached )
495+ list.Add(contrib);
353496 }
354-
355497 return list.ToArray(contributionType);
356498 }
357499
500+ public IEnumerable<Contribution> EnumContributions(Type contributionType, bool hideDisabled) {
501+ return new ContributionEnumerator(contributionType, hideDisabled);
502+ }
358503
504+
359505 /// <summary>
360506 /// Gets all contributions.
361507 /// </summary>
362- public Contribution[] Contributions {
508+ public IEnumerable<Contribution> Contributions {
363509 get {
364- ArrayList list = new ArrayList();
365- foreach( Plugin p in plugins )
366- foreach( Contribution contrib in p.Contributions )
367- list.Add(contrib);
368-
369- return (Contribution[])list.ToArray(typeof(Contribution));
510+ return new ContributionEnumerator(false);
370511 }
371512 }
372513
373- private Contribution[] PrimitiveContributions {
514+ public IEnumerable<Plugin> Plugins {
374515 get {
375- ArrayList list = new ArrayList();
376- foreach (Plugin p in plugins)
377- foreach (Contribution contrib in p.Primitives)
378- list.Add(contrib);
516+ return new PluginEnumerator();
517+ }
518+ }
379519
380- return (Contribution[])list.ToArray(typeof(Contribution));
520+ public IEnumerable<IContributionFactory> Factories {
521+ get {
522+ return new FactoryEnumerator();
381523 }
382524 }
383525
@@ -394,23 +536,15 @@
394536 /// Gets the contribution with a given ID, or null if not found.
395537 /// </summary>
396538 public Contribution GetContribution( string id ) {
397- return (Contribution)contributionMap[id];
539+ return contributionMap[id];
398540 }
399541
400542 /// <summary>
401- /// Enumerates all plug-in objects.
402- /// </summary>
403- public IEnumerator GetEnumerator()
404- {
405- return plugins.GetEnumerator();
406- }
407-
408- /// <summary>
409543 /// Get the plug-in of the specified name, or null if not found.
410544 /// </summary>
411545 public Plugin GetPlugin( string name )
412546 {
413- return (Plugin)pluginMap[name];
547+ return pluginMap[name];
414548 }
415549
416550 public Type GetDefinedType( string ctbType )
@@ -424,10 +558,10 @@
424558
425559 public string GetInstallInfo()
426560 {
427- if(plugins == null )
561+ if (pluginMap.Count == 0)
428562 return "";
429563 string output = "Installed Plugins (except for system plugins).";
430- foreach(Plugin p in plugins)
564+ foreach(Plugin p in pluginMap.Values)
431565 {
432566 if(!p.ID.StartsWith("system"))
433567 {
@@ -437,5 +571,71 @@
437571 }
438572 return output;
439573 }
440- }
574+
575+
576+ internal class FactoryEnumerator : IEnumerable<IContributionFactory>
577+ {
578+ public FactoryEnumerator() {
579+ }
580+
581+ public IEnumerator<IContributionFactory> GetEnumerator() {
582+ foreach (IContributionFactory fct in PluginManager.theInstance.contributionFactories.Values)
583+ yield return fct;
584+ }
585+
586+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
587+ return GetEnumerator();
588+ }
589+ }
590+
591+ internal class PluginEnumerator : IEnumerable<Plugin>
592+ {
593+ public PluginEnumerator() {
594+ }
595+
596+ public IEnumerator<Plugin> GetEnumerator() {
597+ foreach (Plugin p in PluginManager.theInstance.pluginMap.Values)
598+ yield return p;
599+ }
600+
601+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
602+ return GetEnumerator();
603+ }
604+ }
605+
606+ internal class ContributionEnumerator : IEnumerable<Contribution>
607+ {
608+ readonly Type type;
609+ readonly bool hideDisabled;
610+ public ContributionEnumerator(bool hideDisable) : this(null, hideDisable) { }
611+
612+ public ContributionEnumerator(Type t) : this(t, true) { }
613+
614+ public ContributionEnumerator(Type t, bool hideDisable) {
615+ this.type = t;
616+ this.hideDisabled = hideDisable;
617+ }
618+
619+ public IEnumerator<Contribution> GetEnumerator() {
620+ if (type == null) {
621+ foreach (Contribution c in PluginManager.theInstance.contributionMap.Values)
622+ if (!hideDisabled || c.IsAttached)
623+ yield return c;
624+ } else {
625+ foreach (Contribution c in PluginManager.theInstance.contributionMap.Values) {
626+ if (type.IsInstanceOfType(c)) {
627+ if (!hideDisabled || c.IsAttached)
628+ yield return c;
629+ }
630+ }
631+ }
632+ }
633+
634+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
635+ return GetEnumerator();
636+ }
637+ }
638+
639+ }
640+
441641 }
--- framework/framework/plugin/Plugin.cs (revision 3)
+++ framework/framework/plugin/Plugin.cs (revision 4)
@@ -49,16 +49,6 @@
4949 public readonly Uri Uri;
5050
5151 /// <summary>
52- /// All the contributions in this plug-in
53- /// </summary>
54- public readonly IList Contributions = new ArrayList();
55-
56- /// <summary>
57- /// All the contribution definers and binary modules in this plug-in
58- /// </summary>
59- public readonly IList Primitives = new ArrayList();
60-
61- /// <summary>
6252 /// ParamsReader is given from PluginManager and will set null after loading complete.
6353 /// </summary>
6454 internal protected ParamsReader _reader;
@@ -119,6 +109,15 @@
119109 onDetach(this);
120110 }
121111 }
112+
113+ internal void AssociateAddableContribution(Contribution c){
114+ if (c.IsDetachable) {
115+ totalDetachables++;
116+ detachable = true;
117+ c.OnAttach += new AttachChangeEvent(this.AttachChangeEventHandler);
118+ c.OnDetach += new AttachChangeEvent(this.AttachChangeEventHandler);
119+ }
120+ }
122121 #endregion
123122
124123 /// <summary>
@@ -161,7 +160,33 @@
161160 }
162161 }
163162
163+
164164 /// <summary>
165+ /// All the contributions in this plug-in
166+ /// </summary>
167+ public IList Contributions {
168+ get {
169+ IList l = new ArrayList();
170+ foreach (Contribution c in PluginManager.theInstance.Contributions) {
171+ if (c.Parent == this)
172+ l.Add(c);
173+ }
174+ return l;
175+ }
176+ }
177+
178+ /// <summary>
179+ /// All the contribution definers and binary modules in this plug-in
180+ /// </summary>
181+ [Obsolete]
182+ public IList Primitives {
183+ get {
184+ return new ArrayList();
185+ }
186+ }
187+
188+ /*
189+ /// <summary>
165190 /// Get all the dependent plug-ins.
166191 /// called from PluginManager before initialize this plugin.
167192 /// </summary>
@@ -223,7 +248,7 @@
223248 } else {
224249 continue;
225250 }
226- if (Contribution.isPrimitiveContribution(cb.GetType())) {
251+ if (Contribution.IsPrimitiveContribution(cb.GetType())) {
227252 Primitives.Add(cb);
228253 } else {
229254 Contributions.Add(cb);
@@ -243,9 +268,12 @@
243268 /// </summary>
244269 internal void loadContributions() {
245270 Contribution c = null;
271+ int count = 0;
272+ int errors = 0;
246273 // load contributions
247274 foreach (ParamsReader contrib in _reader.EnumChildren("contribution")) {
248275 try {
276+ count++;
249277 string type = contrib["type"].InnerText;
250278 if ("factory".Equals(type) || "binary".Equals(type)) continue; // ignore
251279
@@ -263,6 +291,7 @@
263291 PluginManager.theInstance.AddContribution(c);
264292 c._state = InstallationState.Ready;
265293 } catch (Exception e) {
294+ errors++;
266295 Debug.WriteLine(e.Message);
267296 Debug.WriteLine(e.StackTrace);
268297 if (e.InnerException != null) {
@@ -272,14 +301,16 @@
272301 if (c != null)
273302 c._state = InstallationState.FatalError;
274303 string msg = MakeContribExceptionMessage(contrib);
275-
276- if(_state != InstallationState.FatalError)
277- _state = InstallationState.PartialError;
278- PluginManager.theInstance.ReportError(msg,e);
304+ if (_state != InstallationState.FatalError)
305+ _state = InstallationState.PartialError;
306+ PluginManager.theInstance.ReportError(msg, e);
279307 }
280308 }
281- if (_state == InstallationState.Uninitialized)
309+ if (_state != InstallationState.FatalError && errors == count) {
310+ _state = InstallationState.FatalError;
311+ } else if (_state == InstallationState.Uninitialized) {
282312 _state = InstallationState.Ready;
313+ }
283314 }
284315
285316 private string MakeContribExceptionMessage(ParamsReader pr) {
@@ -288,5 +319,6 @@
288319 string _name = pr["name"].InnerTextOr("unknown");
289320 return string.Format(templ, Uri.AbsoluteUri, _name, _id);
290321 }
322+ */
291323 }
292324 }
--- framework/framework/plugin/PluginXmlException.cs (revision 3)
+++ framework/framework/plugin/PluginXmlException.cs (revision 4)
@@ -39,7 +39,7 @@
3939 if(plugin==null)
4040 {
4141 string pname = Path.GetFileName(Path.GetDirectoryName(node.SourceURI)+"");
42- plugin = Main.plugins.GetPlugin(pname);
42+ plugin = PluginManager.theInstance.GetPlugin(pname);
4343 }
4444 }
4545
--- framework/util/ContribListControlHelper.cs (revision 3)
+++ framework/util/ContribListControlHelper.cs (revision 4)
@@ -2,6 +2,7 @@
22 using System.Windows.Forms;
33 using nft.framework;
44 using nft.framework.plugin;
5+using System.Collections.Generic;
56
67 namespace nft.util
78 {
@@ -14,10 +15,10 @@
1415
1516 public static int Set( ComboBox combo, string ctbType, bool hideDisabled, IListContribFilter filter )
1617 {
17- Array arr = GetArray( ctbType, hideDisabled );
18- if( arr == null ) return -1;
18+ IEnumerable<Contribution> en = GetArray( ctbType, hideDisabled );
19+ if( en == null ) return -1;
1920 int n = 0;
20- foreach( Contribution c in arr )
21+ foreach( Contribution c in en )
2122 if(filter.IsValid(c))
2223 {
2324 combo.Items.Add( new AbstractItem(c) );
@@ -65,12 +66,12 @@
6566 }
6667 }
6768
68- private static Array GetArray( string ctbType, bool hideDisabled )
69+ private static IEnumerable<Contribution> GetArray( string ctbType, bool hideDisabled )
6970 {
7071 PluginManager pm = PluginManager.theInstance;
7172 Type t = pm.GetDefinedType(ctbType);
7273 if( t == null ) return null;
73- return pm.ListContributions(t,hideDisabled);
74+ return pm.EnumContributions(t,hideDisabled);
7475 }
7576
7677 #region Default Filter
--- ui_jp/ui/system/ErrorMessageBox.cs (revision 3)
+++ ui_jp/ui/system/ErrorMessageBox.cs (revision 4)
@@ -61,8 +61,8 @@
6161 sb.AppendLine("-----System Information-----");
6262 sb.AppendLine(ConfigureService.GetSystemInfo());
6363 sb.AppendLine("-----PlugIn Information-----");
64- if (Main.plugins != null) {
65- sb.AppendLine(Main.plugins.GetInstallInfo());
64+ if (Main.pluginManager != null) {
65+ sb.AppendLine(Main.pluginManager.GetInstallInfo());
6666 } else {
6767 sb.AppendLine("Plugin manager not initialized.");
6868 }
--- ui_jp/ui/system/PluginListDialog.cs (revision 3)
+++ ui_jp/ui/system/PluginListDialog.cs (revision 4)
@@ -1,6 +1,7 @@
11 using System;
22 using System.Drawing;
33 using System.Collections;
4+using System.Collections.Generic;
45 using System.ComponentModel;
56 using System.Windows.Forms;
67 using nft.framework;
@@ -9,6 +10,7 @@
910 using nft.util;
1011 using nft.win32util;
1112 using nft.controls;
13+using System.IO;
1214
1315 namespace nft.ui.system
1416 {
@@ -293,13 +295,17 @@
293295 // populate the list
294296 clist.Items.Clear();
295297 plist.Items.Clear();
296- foreach( Plugin p in Main.plugins )
298+ foreach( Plugin p in PluginManager.theInstance.Plugins )
297299 plist.Items.Add( CreateListItem(p) );
298300
299301 // construct tree
300302 tree.Nodes.Clear();
301- foreach( Plugin p in Main.plugins )
302- tree.Nodes.Add( CreateTreeItem(p) );
303+ foreach (IContributionFactory f in PluginManager.theInstance.Factories) {
304+ Type t = f.OutputType;
305+ tree.Nodes.Add(CreateTreeItem(f));
306+ }
307+ //foreach (Plugin p in PluginManager.theInstance.Plugins)
308+ //tree.Nodes.Add( CreateTreeItem(p) );
303309 }
304310
305311 private void list_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
@@ -323,24 +329,52 @@
323329 {
324330 Application.DoEvents();
325331 Plugin p = (Plugin)item.Tag;
326- foreach (Contribution c in p.Primitives)
327- clist.Items.Add( CreateListItem(c) );
328- foreach( Contribution c in p.Contributions )
329- clist.Items.Add( CreateListItem(c) );
330- }
332+ foreach (Contribution c in p.Contributions) {
333+ clist.Items.Add(CreateListItem(c));
334+ }
335+ }
331336 }
332337
333338 private void tree_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
334339 {
335- Plugin p = e.Node.Tag as Plugin;
340+ IContributionFactory f = e.Node.Tag as IContributionFactory;
341+ if (f != null) {
342+ e.Node.Nodes.Clear();
343+ foreach (Contribution c in PluginManager.theInstance.EnumContributions(f.OutputType,false)) {
344+ Plugin p = c.Parent;
345+ TreeNode pnode = null;
346+ foreach (TreeNode tn in e.Node.Nodes) {
347+ if (tn.Tag == p) {
348+ pnode = tn;
349+ break;
350+ }
351+ }
352+ if (pnode == null) {
353+ pnode = CreateTreeItem(p);
354+ e.Node.Nodes.Add(pnode);
355+ }
356+ pnode.Nodes.Add(CreateTreeItem(c));
357+ }
358+ return;
359+ }
360+ /*
361+ Plugin p = e.Node.Tag as Plugin;
336362 if(p!=null)
337363 {
338364 e.Node.Nodes.Clear();
339- foreach (Contribution c in p.Primitives)
340- e.Node.Nodes.Add( CreateTreeItem(c) );
341- foreach( Contribution c in p.Contributions )
342- e.Node.Nodes.Add( CreateTreeItem(c) );
343- }
365+ List<Contribution> prim = new List<Contribution>();
366+ foreach (Contribution c in p.Contributions) {
367+ if (c.IsPrimitive) {
368+ prim.Add(c);
369+ } else {
370+ e.Node.Nodes.Add(CreateTreeItem(c));
371+ }
372+ }
373+ int i = 0;
374+ foreach (Contribution c in prim)
375+ e.Node.Nodes.Insert(i++,CreateTreeItem(c));
376+ }
377+ */
344378 }
345379
346380 private void tree_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
@@ -347,7 +381,16 @@
347381 {
348382 ShowInfoMessage();
349383 string msg;
350- Plugin p = e.Node.Tag as Plugin;
384+ IContributionFactory f = e.Node.Tag as IContributionFactory;
385+ if (f != null) {
386+ string dllname = Path.GetFileName(new Uri(f.GetType().Assembly.CodeBase).LocalPath);
387+ msg = string.Format("Type:{0}\nFactory:{1}\nCodeBase:{2}", f.OutputType.Name, f.GetType().FullName, dllname);
388+ info.Text = msg;
389+ info.LinkArea = new LinkArea(0, 0);
390+ info.TargetUrl = "";
391+ return;
392+ }
393+ Plugin p = e.Node.Tag as Plugin;
351394 if(p!=null)
352395 {
353396 msg = string.Format("Title:{0}\nAuthor:{1}\nHomepage:{2}",p.Title,p.author,p.homepage);
@@ -368,7 +411,7 @@
368411 Contribution c = e.Node.Tag as Contribution;
369412 if(c!=null)
370413 {
371- msg = string.Format("Name:{0}\nType:{1}",c.Name,c.CtbType);
414+ msg = string.Format("ID:{0}\nName:{1}\nDescription:{2}", c.ID, c.Name, c.Description);
372415 info.Text = msg;
373416 info.LinkArea = new LinkArea(0,0);
374417 info.TargetUrl="";
@@ -396,7 +439,7 @@
396439 switch(c.State)
397440 {
398441 case InstallationState.Ready:
399- if (Contribution.isPrimitiveContribution(c.GetType()))
442+ if (c.IsPrimitive)
400443 return 4;
401444 else
402445 return 1;
@@ -413,6 +456,8 @@
413456 return 0;
414457 case InstallationState.PartialError:
415458 return 3;
459+ case InstallationState.FatalError:
460+ return 5;
416461 default:
417462 return 2;
418463 }
@@ -437,7 +482,7 @@
437482 private TreeNode CreateTreeItem(Contribution c)
438483 {
439484 int icon = GetIconIndex(c);
440- TreeNode node = new TreeNode(c.ID, icon, icon );
485+ TreeNode node = new TreeNode(c.Name, icon, icon );
441486 node.Tag = c;
442487 node.Checked = c.IsAttached;
443488 return node;
@@ -484,9 +529,9 @@
484529 private void tree_BeforeCheck(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
485530 {
486531 TreeNode node = e.Node;
487- IAddable addable = node.Tag as IAddable;
532+ Contribution addable = node.Tag as Contribution;
488533 if(e.Action != TreeViewAction.ByMouse && e.Action !=TreeViewAction.ByKeyboard ) return;
489- if( addable.IsDetachable )
534+ if (addable!=null && addable.IsDetachable)
490535 {
491536 if(node.Checked)
492537 addable.Detach();
@@ -538,15 +583,22 @@
538583 {
539584 }
540585
541- private TreeNode CreateTreeItem(Plugin p)
586+ private TreeNode CreateTreeItem(IContributionFactory f)
542587 {
543- int icon = GetIconIndex(p);
544- TreeNode node = new TreeNode(p.ID, icon, icon, new TreeNode[]{new TreeNode("")} );
545- node.Tag = p;
546- node.Checked = p.IsAttached;
588+ int icon = 6;
589+ TreeNode node = new TreeNode(f.OutputType.Name, icon, icon, new TreeNode[]{new TreeNode("")} );
590+ node.Tag = f;
591+ node.Checked = true;
547592 return node;
548593 }
549- #endregion
594+ private TreeNode CreateTreeItem(Plugin p) {
595+ int icon = GetIconIndex(p);
596+ TreeNode node = new TreeNode(p.ID, icon, icon);
597+ node.Tag = p;
598+ node.Checked = p.IsAttached;
599+ return node;
600+ }
601+ #endregion
550602
551603 internal class Sorter : IComparer
552604 {