public static void InitializePlugins(string[] plugindirs, ProgressHandler progressHandler, PluginErrorHandler errorHandler) { if (initialized) { Clear(); } if (MainWindow.mainWindow == null) { MainWindow.mainWindow = new MainWindow(plugindirs, false); } if (progressHandler == null) { progressHandler = new ProgressHandler(SilentProgress); } IList r = new ArrayList(); string baseDir = PluginManager.getDefaultPluginDirectory(); foreach (string subdir in Directory.GetDirectories(baseDir)) { r.Add(Path.Combine(baseDir, subdir)); } // load plug-ins Core.plugins.init(r, progressHandler, errorHandler); if (World.world == null) { World.world = new World(new Distance(5, 5, 5), 0); } initialized = true; }
/// <summary> /// This method should be called after the object is created. /// </summary> /// <param name="dirs"> /// collection of strings (directory names) /// for each directory in this collection, its sub-directories /// are scanned for plugin.xml /// </param> public void init(ICollection dirs, ProgressHandler progressHandler, PluginErrorHandler errorHandler) { Set pluginSet = new Set(); Hashtable errorPlugins = new Hashtable(); int errCount = 0; int count = 0; float c_max = dirs.Count * 4; bool errBreak = false; if (errorHandler == null) { errorHandler = new SilentPluginErrorHandler(); } // locate plugins foreach (string dir in dirs) { progressHandler("Searching for plugins...\n" + Path.GetFileName(dir), ++count / c_max); //! progressHandler("プラグインを検索中\n"+Path.GetFileName(dir),++count/c_max); if (!File.Exists(Path.Combine(dir, "plugin.xml"))) { continue; // this directory doesn't have the plugin.xml file. } Plugin p = null; try { p = new Plugin(dir); p.loadContributionFactories(); } catch (Exception e) { errCount++; p = Plugin.loadFailSafe(dir); errorPlugins.Add(p, e); errBreak = errorHandler.OnPluginLoadError(p, e); if (errBreak) { break; } else { continue; } } if (pluginMap.Contains(p.name)) { errCount++; // loaded more than once Exception e = new Exception(string.Format( "Plugin \"{0}\" is loaded from more than one place ({1} and {2})", //! "プラグイン「{0}」は{1}と{2}の二箇所からロードされています", p.name, p.dirName, ((Plugin)pluginMap[p.name]).dirName)); errBreak = errorHandler.OnNameDuplicated(pluginMap[p.name] as Plugin, p, e); errorPlugins.Add(p, e); if (errBreak) { break; } else { continue; } } pluginMap.Add(p.name, p); pluginSet.add(p); } if (errBreak) { Environment.Exit(-1); } { // convert it to an array by sorting them in the order of dependency this.plugins = new Plugin[pluginSet.count]; int ptr = 0; Plugin p = null; while (!pluginSet.isEmpty) { progressHandler("Sorting dependencies...", ++count / c_max); //! progressHandler("依存関係を整理中",++count/c_max); p = (Plugin)pluginSet.getOne(); try { while (true) { Plugin[] deps = p.getDependencies(); int i; for (i = 0; i < deps.Length; i++) { if (pluginSet.contains(deps[i])) { break; } } if (i == deps.Length) { break; } else { p = deps[i]; } } } catch (Exception e) { errCount++; errBreak = errorHandler.OnPluginLoadError(p, e); if (!errorPlugins.ContainsKey(p)) { errorPlugins.Add(p, e); } if (errBreak) { break; } } pluginSet.remove(p); plugins[ptr++] = p; } } if (errBreak) { Environment.Exit(-2); } // load all the contributions foreach (Plugin p in plugins) { progressHandler("Loading contributions...\n" + Path.GetFileName(p.dirName), ++count / c_max); //! progressHandler("コントリビューションをロード中\n"+Path.GetFileName(p.dirName),++count/c_max); try { p.loadContributions(); } catch (Exception e) { errCount++; errBreak = errorHandler.OnPluginLoadError(p, e); if (!errorPlugins.ContainsKey(p)) { errorPlugins.Add(p, e); } if (errBreak) { break; } } } if (errBreak) { Environment.Exit(-3); } // initialize contributions count = (int)c_max; c_max += publicContributions.Length; foreach (Contribution contrib in publicContributions) { progressHandler("Initializing contributions...\n" + contrib.baseUri, ++count / c_max); //! progressHandler("コントリビューションを初期化中\n"+contrib.baseUri,++count/c_max); try { contrib.onInitComplete(); } catch (Exception e) { errCount++; errBreak = errorHandler.OnContributionInitError(contrib, e); Plugin p = contrib.parent; if (!errorPlugins.ContainsKey(p)) { errorPlugins.Add(p, e); } if (errBreak) { break; } } } if (errBreak) { Environment.Exit(-4); } { // make sure there's no duplicate id progressHandler("Checking for duplicate IDs...", 1.0f); //! progressHandler("重複IDのチェック中",1.0f); IDictionary dic = new Hashtable(); foreach (Contribution contrib in publicContributions) { if (dic[contrib.id] != null) { errCount++; Exception e = new FormatException("ID:" + contrib.id + " is not unique"); //! Exception e = new FormatException("ID:"+contrib.id+"が一意ではありません"); errBreak = errorHandler.OnContribIDDuplicated(dic[contrib.id] as Contribution, contrib, e); Plugin p = contrib.parent; if (!errorPlugins.ContainsKey(p)) { errorPlugins.Add(p, e); } if (errBreak) { break; } } else { dic[contrib.id] = contrib; } } } if (errBreak) { Environment.Exit(-5); } if (errCount > 0) { if (errorHandler.OnFinal(errorPlugins, errCount)) { Environment.Exit(errCount); } } }