private void Instantiate() { foreach (Plugin p in _orderedPlugins) { try { if (p.Instantiate() == GenericResult.Failed) { _tracer.Trace("PluginManager.Messages.PluginInitializeFailed", p.PluginInfo.ID); continue; } _currentInitializingPlugin = p; p.Instance.InitializePlugin(_world); _currentInitializingPlugin = null; } catch (Exception ex) { _tracer.Trace("PluginManager.Messages.PluginInitializeFailed", p.PluginInfo.ID); _tracer.Trace(ex); } } }
private void Order() { List<Plugin> unordered = new List<Plugin>(); _orderedPlugins = new List<Plugin>(); //TODO �ȒP�̂��߂ɃR�A�����̏��Ԃ̓Y�����Đݒ肵�����@���Ƃ��Aid��org.poderosa.core�Ŏn�܂��̂͗D�悷��Ȃ� foreach (Plugin p in _allPlugins) { if (p.Status == PluginStatus.Loaded) { string d = p.PluginInfo.Dependencies; if (d == null || d.Length == 0) { _orderedPlugins.Add(p); //���ɂ�ˑ����Ă��Ȃ��z�͐�ɓ���Ă��� continue; } string[] t = d.Split(';'); Plugin[] dependencies = new Plugin[t.Length]; bool failed = false; for (int i = 0; i < t.Length; i++) { //TODO �o�[�W�����w�����T�|�[�g�H Plugin r = _idToPlugin[t[i]]; if (r == null || r.Status == PluginStatus.Disabled) { _tracer.Trace("PluginManager.Messages.DependencyNotFound", p.TypeName, t[i]); failed = true; break; } dependencies[i] = r; } if (failed) { p.Disable(); } else { //success p.Dependencies = dependencies; unordered.Add(p); } } } //���Ԃ̍쐬 while (unordered.Count > 0) { bool found = false; for (int i = 0; i < unordered.Count; i++) { Plugin p = unordered[i]; Plugin dep = FindDisabledPlugin(p.Dependencies); if (dep != null) { _tracer.Trace("PluginManager.Messages.DependencyNotFound", p.TypeName, dep.PluginInfo.ID); unordered.RemoveAt(i); //���߂Ȃ̂������Ă��邱�Ƃ����B���̂Ƃ���ordered�ɂ͂��ꂸ�ɔ����� found = true; break; //for������ } if (AllContainedInOrderedPlugins(p.Dependencies)) { unordered.RemoveAt(i); _orderedPlugins.Add(p); found = true; break; //for������ } } if (!found) { //�ꏄ���ď����ł��Ȃ�������z�ˑ������� _tracer.Trace("PluginManager.Messages.DependencyLoopError", FormatIDs(unordered)); break; //while���� } } }
private Plugin FindDisabledPlugin(Plugin[] ps) { foreach (Plugin p in ps) if (p.Status == PluginStatus.Disabled) return p; return null; }
// Enumerate plugins according to the specified node. private IEnumerable<Plugin> EnumeratePlugins(PluginManager manager, Assembly assembly, PluginManifest.AssemblyEntry assemblyEntry, ITracer tracer) { foreach (string pluginTypeName in assemblyEntry.PluginTypes) { Type pluginType; try { pluginType = assembly.GetType(pluginTypeName); } catch (Exception) { tracer.Trace("PluginManager.Messages.TypeLoadError", assembly.CodeBase, pluginTypeName); continue; } if (pluginType == null) { tracer.Trace("PluginManager.Messages.TypeLoadError", assembly.CodeBase, pluginTypeName); continue; } Plugin plugin = new Plugin(manager, assembly, pluginType); yield return plugin; } }
// Enumerate plugins from the specified assembly. private IEnumerable<Plugin> EnumeratePlugins(PluginManager manager, Assembly assembly, ITracer tracer) { PluginDeclarationAttribute[] decls = (PluginDeclarationAttribute[])assembly.GetCustomAttributes(typeof(PluginDeclarationAttribute), false); foreach (PluginDeclarationAttribute decl in decls) { Plugin plugin = new Plugin(manager, assembly, decl.Target); yield return plugin; } }
private bool AllContainedInOrderedPlugins(Plugin[] ps) { foreach (Plugin p in ps) if (!_orderedPlugins.Contains(p)) return false; return true; }
private void Order() { List<Plugin> unordered = new List<Plugin>(); _orderedPlugins = new List<Plugin>(); //TODO 簡単のためにコア部分の順番はズルして設定したい たとえば、idがorg.poderosa.coreで始まるものは優先するなど foreach (Plugin p in _allPlugins) { if (p.Status == PluginStatus.Loaded) { string d = p.PluginInfo.Dependencies; if (d == null || d.Length == 0) { _orderedPlugins.Add(p); //何にも依存していない奴は先に入れておく continue; } string[] t = d.Split(';'); Plugin[] dependencies = new Plugin[t.Length]; bool failed = false; for (int i = 0; i < t.Length; i++) { //TODO バージョン指定つきをサポート? Plugin r = _idToPlugin[t[i]]; if (r == null || r.Status == PluginStatus.Disabled) { _tracer.Trace("PluginManager.Messages.DependencyNotFound", p.TypeName, t[i]); failed = true; break; } dependencies[i] = r; } if (failed) { p.Disable(); } else { //success p.Dependencies = dependencies; unordered.Add(p); } } } //順番の作成 while (unordered.Count > 0) { bool found = false; for (int i = 0; i < unordered.Count; i++) { Plugin p = unordered[i]; Plugin dep = FindDisabledPlugin(p.Dependencies); if (dep != null) { _tracer.Trace("PluginManager.Messages.DependencyNotFound", p.TypeName, dep.PluginInfo.ID); unordered.RemoveAt(i); //だめなのが入っていることもある。そのときはorderedにはいれずに抜ける found = true; break; //for文を抜ける } if (AllContainedInOrderedPlugins(p.Dependencies)) { unordered.RemoveAt(i); _orderedPlugins.Add(p); found = true; break; //for文を抜ける } } if (!found) { //一巡して除去できなかったら循環依存がある _tracer.Trace("PluginManager.Messages.DependencyLoopError", FormatIDs(unordered)); break; //whileを抜ける } } }