/// <summary> /// スクリプトを読み込み、コンパイルします。 /// </summary> public static void reload() { // 拡張子がcs, txtのファイルを列挙 String dir = Utility.getScriptPath(); Vector <String> files = new Vector <String>(); files.addAll(Arrays.asList(PortUtil.listFiles(dir, ".txt"))); files.addAll(Arrays.asList(PortUtil.listFiles(dir, ".cs"))); // 既存のスクリプトに無いまたは新しいやつはロード。 Vector <String> added = new Vector <String>(); //追加または更新が行われたスクリプトのID foreach (String file in files) { String id = PortUtil.getFileName(file); double time = PortUtil.getFileLastModified(file); added.add(id); boolean loadthis = true; if (scripts.containsKey(id)) { double otime = scripts.get(id).fileTimestamp; if (time <= otime) { // 前回コンパイルした時点でのスクリプトファイルよりも更新日が同じか古い。 loadthis = false; } } // ロードする処理 if (!loadthis) { continue; } ScriptInvoker si = (new PluginLoader()).loadScript(file); scripts.put(id, si); } // 削除されたスクリプトがあれば登録を解除する boolean changed = true; while (changed) { changed = false; for (Iterator <String> itr = scripts.keySet().iterator(); itr.hasNext();) { String id = itr.next(); if (!added.contains(id)) { scripts.remove(id); changed = true; break; } } } }
/// <summary> /// スクリプトを読み込み、コンパイルします。 /// </summary> public static void reload() { // 拡張子がcs, txtのファイルを列挙 string dir = Utility.getScriptPath(); List <string> files = new List <string>(); files.AddRange(new List <string>(PortUtil.listFiles(dir, ".txt"))); files.AddRange(new List <string>(PortUtil.listFiles(dir, ".cs"))); // 既存のスクリプトに無いまたは新しいやつはロード。 List <string> added = new List <string>(); //追加または更新が行われたスクリプトのID foreach (string file in files) { string id = PortUtil.getFileName(file); double time = PortUtil.getFileLastModified(file); added.Add(id); bool loadthis = true; if (scripts.ContainsKey(id)) { double otime = scripts[id].fileTimestamp; if (time <= otime) { // 前回コンパイルした時点でのスクリプトファイルよりも更新日が同じか古い。 loadthis = false; } } // ロードする処理 if (!loadthis) { continue; } ScriptInvoker si = (new PluginLoader()).loadScript(file); scripts[id] = si; } // 削除されたスクリプトがあれば登録を解除する bool changed = true; while (changed) { changed = false; foreach (var id in scripts.Keys) { if (!added.Contains(id)) { scripts.Remove(id); changed = true; break; } } } }
/// <summary> /// 指定したIDのスクリプトを再読込みするか、または新規の場合読み込んで追加します。 /// </summary> /// <param name="id"></param> public static void reload(String id) { String dir = Utility.getScriptPath(); String file = Path.Combine(dir, id); #if DEBUG sout.println("ScriptServer#reload; file=" + file + "; isFileExists(file)=" + System.IO.File.Exists(file)); #endif if (!System.IO.File.Exists(file)) { return; } ScriptInvoker si = (new PluginLoader()).loadScript(file); scripts.put(id, si); }
/// <summary> /// 指定したIDが示すスクリプトの、表示上の名称を取得します。 /// </summary> /// <param name="id"></param> /// <returns></returns> public static String getDisplayName(String id) { if (scripts.containsKey(id)) { ScriptInvoker invoker = scripts.get(id); if (invoker.getDisplayNameDelegate != null) { String ret = ""; try { ret = invoker.getDisplayNameDelegate(); } catch (Exception ex) { serr.println("ScriptServer#getDisplayName; ex=" + ex); ret = PortUtil.getFileNameWithoutExtension(id); } return(ret); } } return(PortUtil.getFileNameWithoutExtension(id)); }
public void loadTest() { PluginLoader.cleanupUnusedAssemblyCache(); var files = from file in PortUtil.listFiles("./fixture/script", "") where file.EndsWith(".cs") | file.EndsWith(".txt") select file; foreach (var file in files) { var loader = new PluginLoader(); ScriptInvoker invoker = null; Assert.DoesNotThrow(() => { invoker = loader.loadScript(file); }); Assert.IsNotNull(invoker); Console.Error.WriteLine(file + "\n" + invoker.ErrorMessage); Assert.IsNotNull(invoker.scriptDelegate); } }
/// <summary> /// スクリプトを実行します。 /// </summary> /// <param name="evsd"></param> public static boolean invokeScript(String id, VsqFileEx vsq) { ScriptInvoker script_invoker = null; if (scripts.containsKey(id)) { script_invoker = scripts.get(id); } else { return(false); } if (script_invoker != null && script_invoker.scriptDelegate != null) { try { VsqFileEx work = (VsqFileEx)vsq.clone(); ScriptReturnStatus ret = ScriptReturnStatus.ERROR; if (script_invoker.scriptDelegate is EditVsqScriptDelegate) { boolean b_ret = ((EditVsqScriptDelegate)script_invoker.scriptDelegate).Invoke(work); if (b_ret) { ret = ScriptReturnStatus.EDITED; } else { ret = ScriptReturnStatus.ERROR; } } else if (script_invoker.scriptDelegate is EditVsqScriptDelegateEx) { boolean b_ret = ((EditVsqScriptDelegateEx)script_invoker.scriptDelegate).Invoke(work); if (b_ret) { ret = ScriptReturnStatus.EDITED; } else { ret = ScriptReturnStatus.ERROR; } } else if (script_invoker.scriptDelegate is EditVsqScriptDelegateWithStatus) { ret = ((EditVsqScriptDelegateWithStatus)script_invoker.scriptDelegate).Invoke(work); } else if (script_invoker.scriptDelegate is EditVsqScriptDelegateExWithStatus) { ret = ((EditVsqScriptDelegateExWithStatus)script_invoker.scriptDelegate).Invoke(work); } else { ret = ScriptReturnStatus.ERROR; } if (ret == ScriptReturnStatus.ERROR) { AppManager.showMessageBox(_("Script aborted"), "Cadencii", cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_INFORMATION_MESSAGE); } else if (ret == ScriptReturnStatus.EDITED) { CadenciiCommand run = VsqFileEx.generateCommandReplace(work); AppManager.editHistory.register(vsq.executeCommand(run)); } String config_file = configFileNameFromScriptFileName(script_invoker.ScriptFile); FileOutputStream fs = null; boolean delete_xml_when_exit = false; // xmlを消すときtrue try { fs = new FileOutputStream(config_file); script_invoker.Serializer.serialize(fs, null); } catch (Exception ex) { serr.println("AppManager#invokeScript; ex=" + ex); delete_xml_when_exit = true; } finally { if (fs != null) { try { fs.close(); if (delete_xml_when_exit) { PortUtil.deleteFile(config_file); } } catch (Exception ex2) { serr.println("AppManager#invokeScript; ex2=" + ex2); } } } return(ret == ScriptReturnStatus.EDITED); } catch (Exception ex) { AppManager.showMessageBox(_("Script runtime error:") + " " + ex, _("Error"), cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_INFORMATION_MESSAGE); serr.println("AppManager#invokeScript; ex=" + ex); } } else { AppManager.showMessageBox(_("Script compilation failed."), _("Error"), cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_WARNING_MESSAGE); } return(false); }
/// <summary> /// 指定されたファイルを読み込んでスクリプトをコンパイルします. /// </summary> /// <param name="file">スクリプトを発動するのに使用するコンテナを返します.</param> /// <returns></returns> #if ENABLE_SCRIPT public ScriptInvoker loadScript(String file) { ScriptInvoker ret = new ScriptInvoker(); ret.ScriptFile = file; ret.fileTimestamp = PortUtil.getFileLastModified(file); // スクリプトの記述のうち、以下のリストに当てはまる部分は空文字に置換される string config_file = ScriptServer.configFileNameFromScriptFileName(file); string script = ""; using (StreamReader sr = new StreamReader(file)) { script += sr.ReadToEnd(); } var code = createPluginCode(script); ret.ErrorMessage = ""; List <string> errors = new List <string>(); Assembly testAssembly = compileScript(code, errors); if (testAssembly == null) { ret.scriptDelegate = null; if (errors.Count == 0) { ret.ErrorMessage = "failed compiling"; } else { for (int i = 0; i < errors.Count; i++) { ret.ErrorMessage += errors[i] + "\r\n"; } } return(ret); } else { foreach (Type implemented in testAssembly.GetTypes()) { Object scriptDelegate = null; ScriptDelegateGetDisplayName getDisplayNameDelegate = null; MethodInfo get_displayname_delegate = implemented.GetMethod("GetDisplayName", new Type[] { }); if (get_displayname_delegate != null && get_displayname_delegate.IsStatic && get_displayname_delegate.IsPublic) { if (get_displayname_delegate.ReturnType.Equals(typeof(String))) { getDisplayNameDelegate = (ScriptDelegateGetDisplayName)Delegate.CreateDelegate(typeof(ScriptDelegateGetDisplayName), get_displayname_delegate); } } MethodInfo tmi = implemented.GetMethod("Edit", new Type[] { typeof(VsqFile) }); if (tmi != null && tmi.IsStatic && tmi.IsPublic) { if (tmi.ReturnType.Equals(typeof(bool))) { scriptDelegate = (EditVsqScriptDelegate)Delegate.CreateDelegate(typeof(EditVsqScriptDelegate), tmi); } else if (tmi.ReturnType.Equals(typeof(ScriptReturnStatus))) { scriptDelegate = (EditVsqScriptDelegateWithStatus)Delegate.CreateDelegate(typeof(EditVsqScriptDelegateWithStatus), tmi); } } tmi = implemented.GetMethod("Edit", new Type[] { typeof(VsqFileEx) }); if (tmi != null && tmi.IsStatic && tmi.IsPublic) { if (tmi.ReturnType.Equals(typeof(bool))) { scriptDelegate = (EditVsqScriptDelegateEx)Delegate.CreateDelegate(typeof(EditVsqScriptDelegateEx), tmi); } else if (tmi.ReturnType.Equals(typeof(ScriptReturnStatus))) { scriptDelegate = (EditVsqScriptDelegateExWithStatus)Delegate.CreateDelegate(typeof(EditVsqScriptDelegateExWithStatus), tmi); } } if (scriptDelegate != null) { ret.ScriptType = implemented; ret.scriptDelegate = scriptDelegate; ret.Serializer = new XmlStaticMemberSerializerEx(implemented); ret.getDisplayNameDelegate = getDisplayNameDelegate; if (!File.Exists(config_file)) { continue; } // 設定ファイルからDeserialize System.IO.FileStream fs = null; bool delete_when_exit = false; try { fs = new System.IO.FileStream(config_file, System.IO.FileMode.Open, System.IO.FileAccess.Read); ret.Serializer.deserialize(fs); } catch (Exception ex) { serr.println("Utility#loadScript; ex=" + ex); Logger.write(typeof(Utility) + ".loadScript; ex=" + ex + "\n"); delete_when_exit = true; } finally { if (fs != null) { try { fs.Close(); if (delete_when_exit) { System.IO.File.Delete(config_file); } } catch (Exception ex2) { serr.println("Utility#loadScript; ex2=" + ex2); Logger.write(typeof(Utility) + ".loadScritp; ex=" + ex2 + "\n"); } } } } else { ret.ErrorMessage = _("'Edit' Method not implemented"); } } } return(ret); }