public static void GenerateVSCodeSnippets() { StringBuilder snippets = new StringBuilder(); VSCodeSnippet snippet = new VSCodeSnippet { body = new string[1] }; foreach (LuaApiInfo api in GetAllApiInfo()) { // Write out the header for the api type LuaApi luaApiDetails = api.Attribute; // Iterate all methods foreach (LuaFunction_Info method in api.functions) { // Grab the LuaApiFunction if it exists LuaApiFunction luaMethodDetails = method.Attribute; snippet.prefix = string.Format("{0}.{1}", luaApiDetails.luaName, luaMethodDetails.name); string paramString = string.Empty; var paramArray = method.MethodInfo.GetParameters(); for (int i = 0; i < paramArray.Length; i++) { var param = paramArray[i]; paramString += string.Format("${{{0}:{1}}}, ", i, param.Name); } if (!string.IsNullOrEmpty(paramString)) { paramString = paramString.Remove(paramString.Length - 2, 2); } snippet.body[0] = string.Format("{0}({1})", snippet.prefix, paramString); snippet.description = luaMethodDetails.description; string finalBlock = string.Format("\"{0}\": {1},", snippet.prefix, JsonUtility.ToJson(snippet, true)); snippets.AppendLine(finalBlock); } foreach (LuaVariableInfo fieldInfo in api.variables) { LuaApiVariable luaVariableDetails = fieldInfo.Attribute; snippet.prefix = string.Format("{0}.{1}", luaApiDetails.luaName, luaVariableDetails.name); snippet.body[0] = snippet.prefix; snippet.description = luaVariableDetails.description; string finalBlock = string.Format("\"{0}\" : {1},", snippet.prefix, JsonUtility.ToJson(snippet, true)); snippets.AppendLine(finalBlock); } } EditorGUIUtility.systemCopyBuffer = snippets.ToString(); }
private static int ToString(IntPtr state) { var obj = LuaApi.ToHandle(state, 1).Target; LuaApi.PushString(state, obj.ToString() ?? ""); return(1); }
private static int Gc(IntPtr state) { var handle = LuaApi.ToHandle(state, 1); handle.Free(); return(0); }
static LuaApi GetClassApi(string name, string inherits = null) { LuaApi api; if (s_apiIdx.TryGetValue(name, out api)) { if (api.inherits == null && inherits != null) { api.inherits = inherits; } return(api); } LuaApi parent = s_api; //先获取父命名空间 int at = name.LastIndexOf('.'); if (at != -1) { parent = GetClassApi(name.Substring(0, at)); } api = parent.AddClass(at != -1 ? name.Substring(at + 1) : name, inherits); s_apiIdx[name] = api; return(api); }
internal void PushObject(object obj, IntPtr?stateOverride = null) { var state = stateOverride ?? MainState; Debug.Assert(LuaApi.GetMainState(state) == MainState, "State override did not match main state."); if (obj == null) { LuaApi.PushNil(state); return; } if (obj is IConvertible conv) { switch (conv.GetTypeCode()) { case TypeCode.Boolean: LuaApi.PushBoolean(state, (bool)obj); return; case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: LuaApi.PushInteger(state, conv.ToInt64(null)); return; case TypeCode.UInt64: LuaApi.PushInteger(state, (long)((ulong)conv)); return; case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: LuaApi.PushNumber(state, conv.ToDouble(null)); return; case TypeCode.Char: case TypeCode.String: LuaApi.PushString(state, conv.ToString()); return; default: ObjectBinder.PushNetObject(state, conv); return; } } else if (obj is LuaReference luaReference) { luaReference.PushOnto(state); } else { ObjectBinder.PushNetObject(state, obj); } }
private static void InternalPushNet(IntPtr state, object obj, string metatable) { var handle = GCHandle.Alloc(obj, GCHandleType.Normal); LuaApi.PushHandle(state, handle); LuaApi.GetField(state, LuaApi.RegistryIndex, metatable); LuaApi.SetMetatable(state, -2); }
/// <summary> /// Type=1003 应用被启用<para/> /// 处理 酷Q 的插件启动事件回调 /// </summary> /// <param name="sender">事件的触发对象</param> /// <param name="e">事件的附加参数</param> public void AppEnable(object sender, EventArgs e) { // 当应用被启用后,将收到此事件。 // 如果酷Q载入时应用已被启用,则在_eventStartup(Type=1001,酷Q启动)被调用后,本函数也将被调用一次。 // 如非必要,不建议在这里加载窗口。(可以添加菜单,让用户手动打开窗口) Common.IsRunning = true; //LuaEnv.LuaEnv.RunLua("", "envent/AppEnable.lua"); // MyExample.test(); //if(Common.CqApi.GetLoginQQ() == 751323264)//默认不开启tcp服务器 // HttpListenerPostParaHelper.ListenStart(); //第一次启动,clone下来整个项目 Task.Run(() => { string gitPath = Common.AppDirectory; if (Directory.Exists(gitPath + "lua\\")) { Tool.Timer.TimerRun(); return;//已存在工程,不用再初始化了 } Common.CqApi.AddLoger(Sdk.Cqp.Enum.LogerLevel.Warning, "启动提示", "正在下载初始脚本,请耐心等待,不要重启插件,以免造成不必要的麻烦"); try { Repository.Clone("https://gitee.com/spiritboy/dev.soware.lua.git", gitPath); Tools.CopyDirectory(gitPath + "appdata\\lua\\", gitPath + "lua\\"); Tools.CopyDirectory(gitPath + "appdata\\xml\\", gitPath + "xml\\"); } catch { Common.CqApi.AddFatalError("请手动删除 酷q/data/app/" + LuaApi.GetAppName() + " 文件夹 然后重启插件"); return;//clone失败,还原 } Common.CqApi.AddLoger(Sdk.Cqp.Enum.LogerLevel.Warning, "第一次启动的提示", "初始脚本下载完成,可以使用了\r\n" + "激活 私聊发送 我爱你"); Common.CqApi.AddLoger(Sdk.Cqp.Enum.LogerLevel.Warning, "下载语音资源", "正在下载语音资源,请稍后,请不要重启插件,以免造成不必要的麻烦"); try { Repository.Clone("https://gitee.com/spiritboy/dev.soware.resources.git", gitPath + "resources\\"); string gPath = gitPath.Substring(0, gitPath.LastIndexOf("\\")); gPath = gPath.Substring(0, gPath.LastIndexOf("\\")); gPath = gPath.Substring(0, gPath.LastIndexOf("\\") + 1); Tools.CopyDirectory(gitPath + "resources\\record\\", gPath + "record\\"); } catch { Common.CqApi.AddLoger(Sdk.Cqp.Enum.LogerLevel.Warning, "语音资源下载失败", "请手动删除 酷q/data/app/" + LuaApi.GetAppName() + "resources 文件夹 然后重启插件"); return;//clone失败,还原 } Common.CqApi.AddLoger(Sdk.Cqp.Enum.LogerLevel.Warning, "下载语音资源", "语音资源下载完成"); }); }
internal void PushOnto(IntPtr state) { if (state != Lua.MainState && LuaApi.GetMainState(state) != Lua.MainState) { throw new ArgumentException("Reference cannot be pushed onto the given Lua environment.", nameof(state)); } LuaApi.RawGetI(state, LuaApi.RegistryIndex, _referenceId); }
/// <summary> /// Creates a <see cref="LuaTable"/>. /// </summary> /// <returns>The resulting <see cref="LuaTable"/>.</returns> /// <exception cref="ObjectDisposedException">The <see cref="Lua"/> environment is disposed.</exception> public LuaTable CreateTable() { ThrowIfDisposed(); LuaApi.CreateTable(MainState); var result = (LuaTable)ToObject(-1, LuaType.Table); LuaApi.Pop(MainState, 1); return(result); }
/// <summary> /// Initializes a new instance of the <see cref="Lua"/> class. /// </summary> public Lua() { MainState = LuaApi.NewState(); LuaApi.OpenLibs(MainState); // To clean references, we set a hook that executes after a certain number of instructions have been executed. _cleanReferencesDelegate = CleanReferences; LuaApi.SetHook(MainState, _cleanReferencesDelegate, LuaHookMask.Count, CleanReferencesPeriod); _binder = new ObjectBinder(this); this["using"] = CreateFunction(new Action <string>(ImportNamespace)); }
/// <summary> /// Imports the given type as a global, allowing Lua to access its static members. /// </summary> /// <param name="type">The type.</param> /// <exception cref="ArgumentNullException"><paramref name="type"/> is <c>null</c>.</exception> /// <exception cref="ObjectDisposedException">The <see cref="Lua"/> environment is disposed.</exception> public void ImportType(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } ThrowIfDisposed(); ObjectBinder.PushNetType(MainState, type); var cleanName = type.Name.Split('`')[0]; LuaApi.SetGlobal(MainState, cleanName); }
public LuaApi AddClass(string name, string inherits = null) { if (childs == null) { childs = new Dictionary <string, LuaApi>(); } var api = new LuaApi(); childs[name] = api; api.type = "class"; api.inherits = inherits; return(api); }
public LuaApi AddValue(string name, string valuetype = null) { if (childs == null) { childs = new Dictionary <string, LuaApi>(); } var api = new LuaApi(); childs[name] = api; api.type = "value"; api.valuetype = valuetype != "void" ? valuetype : null; return(api); }
/// <summary> /// Clears all of the key-value pairs. /// </summary> public void Clear() { PushOnto(Lua.MainState); LuaApi.PushNil(Lua.MainState); while (LuaApi.Next(Lua.MainState, -2)) { LuaApi.Pop(Lua.MainState, 1); LuaApi.PushValue(Lua.MainState, -1); LuaApi.PushNil(Lua.MainState); LuaApi.SetTable(Lua.MainState, -4); } LuaApi.Pop(Lua.MainState, 1); }
/// <summary> /// Determines whether the given key exists. /// </summary> /// <param name="key">The key.</param> /// <returns><c>true</c> if <paramref name="key"/> exists, <c>false</c> otherwise.</returns> public bool ContainsKey(object key) { if (key == null) { return(false); } PushOnto(Lua.MainState); Lua.PushObject(key); var type = LuaApi.GetTable(Lua.MainState, -2); var result = type != LuaType.Nil; LuaApi.Pop(Lua.MainState, 2); return(result); }
private void Dispose(bool disposing) { if (_isDisposed) { return; } if (disposing) { GC.SuppressFinalize(this); } LuaApi.Close(MainState); _isDisposed = true; }
/// <summary> /// Creates a <see cref="LuaThread"/> that will run the given <see cref="LuaFunction"/>. /// </summary> /// <param name="function">The <see cref="LuaFunction"/>.</param> /// <returns>The resulting <see cref="LuaThread"/>.</returns> /// <exception cref="ArgumentException"> /// <paramref name="function"/> is tied to a different <see cref="Lua"/> environment. /// </exception> /// <exception cref="ArgumentNullException"><paramref name="function"/> is <c>null</c>.</exception> /// <exception cref="ObjectDisposedException">The <see cref="Lua"/> environment is disposed.</exception> public LuaThread CreateThread(LuaFunction function) { if (function == null) { throw new ArgumentNullException(nameof(function)); } ThrowIfDisposed(); var threadState = LuaApi.NewThread(MainState); function.PushOnto(threadState); var result = (LuaThread)ToObject(-1, LuaType.Thread); LuaApi.Pop(MainState, 1); return(result); }
public LuaApi AddFunction(string name, string args = null, string returns = null, string valuetype = null) { if (childs == null) { childs = new Dictionary <string, LuaApi>(); } var api = new LuaApi(); childs[name] = api; api.type = "function"; api.args = args; api.returns = returns; api.valuetype = valuetype != "void"? valuetype:null; return(api); }
internal object[] Call(object[] args, IntPtr?stateOverride = null, bool isResuming = false) { var state = stateOverride ?? MainState; Debug.Assert(LuaApi.GetMainState(state) == MainState, "State override did not match main state."); Debug.Assert(isResuming || LuaApi.Type(state, -1) == LuaType.Function, "Stack doesn't have function on top."); var oldTop = isResuming ? 0 : LuaApi.GetTop(state) - 1; var numArgs = args.Length; if (oldTop + numArgs > LuaApi.MinStackSize && !LuaApi.CheckStack(state, numArgs)) { throw new LuaException("Not enough stack space for arguments."); } foreach (var arg in args) { PushObject(arg, state); } var status = isResuming ? LuaApi.Resume(state, MainState, numArgs) : LuaApi.PCallK(state, numArgs); if (status != LuaStatus.Ok && status != LuaStatus.Yield) { var errorMessage = LuaApi.ToString(state, -1); LuaApi.Pop(state, 1); throw new LuaException(errorMessage); } // This is a fast path for functions returning nothing since we avoid a SetTop call. var top = LuaApi.GetTop(state); if (top == oldTop) { return(EmptyObjectArray); } if (top + 1 > LuaApi.MinStackSize && !LuaApi.CheckStack(state, 1)) { throw new LuaException("Not enough scratch stack space."); } var results = ToObjects(oldTop + 1, top, state); LuaApi.SetTop(state, oldTop); return(results); }
/// <summary> /// Executes the given string as a Lua chunk. /// </summary> /// <returns>The results.</returns> /// <exception cref="ArgumentNullException"><paramref name="s"/> is <c>null</c>.</exception> /// <exception cref="LuaException">A Lua error occurs.</exception> /// <exception cref="ObjectDisposedException">The <see cref="Lua"/> environment is disposed.</exception> public object[] DoString(string s) { if (s == null) { throw new ArgumentNullException(nameof(s)); } ThrowIfDisposed(); if (LuaApi.LoadString(MainState, s) != LuaStatus.Ok) { var errorMessage = LuaApi.ToString(MainState, -1); LuaApi.Pop(MainState, 1); throw new LuaException(errorMessage); } return(Call(EmptyObjectArray)); }
/// <summary> /// Creates a <see cref="LuaFunction"/> from the given string as a Lua chunk. /// </summary> /// <returns>The resulting <see cref="LuaFunction"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="s"/> is <c>null</c>.</exception> /// <exception cref="LuaException">A Lua error occurs.</exception> /// <exception cref="ObjectDisposedException">The <see cref="Lua"/> environment is disposed.</exception> public LuaFunction CreateFunction(string s) { if (s == null) { throw new ArgumentNullException(nameof(s)); } ThrowIfDisposed(); if (LuaApi.LoadString(MainState, s) != LuaStatus.Ok) { var errorMessage = LuaApi.ToString(MainState, -1); LuaApi.Pop(MainState, 1); throw new LuaException(errorMessage); } var result = (LuaFunction)ToObject(-1, LuaType.Function); LuaApi.Pop(MainState, 1); return(result); }
private void CleanReferences(IntPtr state, IntPtr debug) { var deadPointers = new List <IntPtr>(); foreach (var kvp in _cachedLuaReferences) { if (!kvp.Value.IsAlive) { deadPointers.Add(kvp.Key); } } foreach (var deadPointer in deadPointers) { _cachedLuaReferences.Remove(deadPointer); var referenceId = _pointerToReferenceId[deadPointer]; LuaApi.Unref(state, LuaApi.RegistryIndex, referenceId); _pointerToReferenceId.Remove(deadPointer); } }
/// <summary> /// Gets an enumerator iterating through the key-value pairs. /// </summary> /// <returns>An enumerator iterating through the key-value pairs.</returns> public IEnumerator <KeyValuePair <object, object> > GetEnumerator() { object currentKey = null; while (true) { PushOnto(Lua.MainState); Lua.PushObject(currentKey); if (!LuaApi.Next(Lua.MainState, -2)) { LuaApi.Pop(Lua.MainState, 1); yield break; } currentKey = Lua.ToObject(-2); var value = Lua.ToObject(-1); LuaApi.Pop(Lua.MainState, 3); yield return(new KeyValuePair <object, object>(currentKey, value)); } }
private static int WrappedCall(IntPtr state, Func <int> function) { var oldTop = LuaApi.GetTop(state); try { LuaApi.PushBoolean(state, true); return(function() + 1); } catch (Exception e) { // If an exception occurs, then we need to reset the top. We don't know what state the stack is in! LuaApi.SetTop(state, oldTop); LuaApi.PushBoolean(state, false); if (e is LuaException) { LuaApi.PushString(state, e.Message); } else { LuaApi.PushString(state, $"unhandled .NET exception:\n{e}"); } return(2); } }
/// <summary> /// Gets or sets the value corresponding to the given key. /// </summary> /// <param name="key">The key.</param> /// <returns>The value.</returns> /// <exception cref="ArgumentException"> /// <paramref name="value"/> is a <see cref="LuaReference"/> which is tied to a different <see cref="Lua"/> environment. /// </exception> /// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c> and is set.</exception> public object this[object key] { get { PushOnto(Lua.MainState); Lua.PushObject(key); var type = LuaApi.GetTable(Lua.MainState, -2); var result = Lua.ToObject(-1, type); LuaApi.Pop(Lua.MainState, 2); return(result); } set { if (key == null) { throw new ArgumentNullException(nameof(key)); } PushOnto(Lua.MainState); Lua.PushObject(key); Lua.PushObject(value); LuaApi.SetTable(Lua.MainState, -3); LuaApi.Pop(Lua.MainState, 1); } }
/// <summary> /// Gets or sets the global with the given name. /// </summary> /// <param name="name">The name.</param> /// <returns>The value of the global.</returns> /// <exception cref="ArgumentException"> /// <paramref name="value"/> is a <see cref="LuaReference"/> which is tied to a different <see cref="Lua"/> environment. /// </exception> /// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c>.</exception> /// <exception cref="ObjectDisposedException">The <see cref="Lua"/> environment is disposed.</exception> public object this[string name] { get { if (name == null) { throw new ArgumentNullException(nameof(name)); } ThrowIfDisposed(); var type = LuaApi.GetGlobal(MainState, name); var result = ToObject(-1, type); LuaApi.Pop(MainState, 1); return(result); } set { if (name == null) { throw new ArgumentNullException(nameof(name)); } ThrowIfDisposed(); PushObject(value); LuaApi.SetGlobal(MainState, name); } }
public static void GenAutoComplete() { s_api = new LuaApi(); s_apiIdx.Clear(); s_apiTypeIdx.Clear(); //收集要生成的类 List <ToLuaMenu.BindType> btList = new List <ToLuaMenu.BindType>(); allTypes.Clear(); ToLuaExport.allTypes.Clear(); ToLuaExport.allTypes.AddRange(ToLuaMenu.baseType); ToLuaExport.allTypes.AddRange(CustomSettings.staticClassTypes); for (int i = 0; i < ToLuaExport.allTypes.Count; i++) { btList.Add(new ToLuaMenu.BindType(ToLuaExport.allTypes[i])); } foreach (var bt in CustomSettings.customTypeList) { if (ToLuaExport.allTypes.Contains(bt.type)) { continue; } ToLuaExport.allTypes.Add(bt.type); btList.Add(bt); } GenBindTypes(btList.ToArray(), false); foreach (var bt in allTypes)//做最后的检查,进一步排除一些类 { if (bt.type.IsInterface && bt.type != typeof(System.Collections.IEnumerator)) { continue; } s_apiTypeIdx[bt.type] = bt; } //一些类需要手动加 { ToLuaMenu.BindType bt = new ToLuaMenu.BindType(typeof(Array)); s_apiTypeIdx[bt.type] = bt; GetClassApi("System.Collections.IEnumerable").AddMethod("GetEnumerator", "()", "System.Collections.IEnumerator", "System.Collections.IEnumerator"); } //生成信息 foreach (var bt in s_apiTypeIdx.Values) { GenApi(bt); } //信息转lua类文件 ToLuaExport.allTypes.Clear(); string s; if (!LuaUtil.TryToLua(s_api.childs, out s)) { return; } s = "return " + s; string path = LuaConst.zbsDir; path = path.Replace("lualibs/mobdebug", "api/lua/gameApiGen.lua"); System.IO.File.WriteAllText(path, s, System.Text.Encoding.UTF8); Debug.Log("生成自动提示文件成功:" + path); }
/// <summary> /// Gets a clean function signature /// </summary> /// <returns>The clean function signature.</returns> /// <param name="method">Method.</param> /// <param name="functionAttrib">Function Attribute.</param> /// <param name="apiAttrib">API Attribute.</param> private static string GetCleanFunctionSignature(MethodInfo method, LuaApiFunction functionAttrib, LuaApi apiAttrib) { string apiName = apiAttrib.luaName; string functionName = functionAttrib.name; string paramsString = string.Empty; foreach (ParameterInfo param in method.GetParameters()) { paramsString += string.Format("{0}, ", param.Name); } // Clean up last comma and space if (!string.IsNullOrEmpty(paramsString)) { paramsString = paramsString.Remove(paramsString.Length - 2, 2); } return(string.Format("{0}.{1}({2})", apiName, functionName, paramsString)); }
public static void GenerateAtomSnippets() { StringBuilder snippets = new StringBuilder(); AtomSnippet snippet = new AtomSnippet(); snippets.AppendLine("'.source.lua':"); // Iterate all types deriving from LuaApiBase foreach (LuaApiInfo api in GetAllApiInfo()) { // Write out the header for the api type LuaApi luaApiDetails = api.Attribute; // Iterate all methods foreach (LuaFunction_Info method in api.functions) { // Grab the LuaApiFunction if it exists LuaApiFunction luaMethodDetails = method.Attribute; snippet.Prefix = string.Format("{0}.{1}", luaApiDetails.luaName, luaMethodDetails.name); string paramString = string.Empty; var paramArray = method.MethodInfo.GetParameters(); for (int i = 0; i < paramArray.Length; i++) { var param = paramArray[i]; paramString += string.Format("${{{0}:{1}}}, ", i, param.Name); } if (!string.IsNullOrEmpty(paramString)) { paramString = paramString.Remove(paramString.Length - 2, 2); } snippet.Body = string.Format("{0}({1})", snippet.Prefix, paramString); snippet.Description = luaMethodDetails.description; snippets.AppendLine(snippet.ConstructCSONString()); } foreach (LuaVariableInfo fieldInfo in api.variables) { LuaApiVariable luaVariableDetails = fieldInfo.Attribute; snippet.Prefix = string.Format("{0}.{1}", luaApiDetails.luaName, luaVariableDetails.name); snippet.Body = snippet.Prefix; snippet.Description = luaVariableDetails.description; snippets.AppendLine(snippet.ConstructCSONString()); } } foreach (LuaEnumInfo enumInfo in GetAllEnums()) { foreach (LuaEnumValueInfo enumValueInfo in enumInfo.values) { if (enumValueInfo.Attribute != null && enumValueInfo.Attribute.hidden) { continue; } snippet.Prefix = string.Format("{0}.{1}", enumInfo.Attribute.name, enumValueInfo.StringValue); snippet.Body = snippet.Prefix; snippet.Description = enumValueInfo.Attribute != null ? enumValueInfo.Attribute.description : string.Empty; snippet.DescriptionMoreUrl = string.Empty; snippets.AppendLine(snippet.ConstructCSONString()); } } EditorGUIUtility.systemCopyBuffer = snippets.ToString(); }
private static void GenerateMediaWikiDocs() { Logger.Log(Channel.Lua, "Beginning Lua doc generation for MediaWiki"); string documentationPath = EditorUtility.OpenFolderPanel("Choose a location to place wiki files", string.Empty, string.Empty); if (!string.IsNullOrEmpty(documentationPath)) { // Iterate all types deriving from LuaApiBase foreach (LuaApiInfo api in GetAllApiInfo()) { // Write out the header for the api type LuaApi luaApiDetails = api.Attribute; string apiDocPath = string.Format("{0}/{1}.mediawiki", documentationPath, luaApiDetails.luaName); StreamWriter documentation = File.CreateText(apiDocPath); Logger.Log(Channel.Lua, "Generating documentation for api: {0}", luaApiDetails.luaName); documentation.WriteLine("= {0} =", luaApiDetails.luaName); if (!string.IsNullOrEmpty(luaApiDetails.description)) { documentation.WriteLine("== Description =="); documentation.WriteLine(luaApiDetails.description); } if (!string.IsNullOrEmpty(luaApiDetails.notes)) { documentation.WriteLine("== Notes =="); documentation.WriteLine(luaApiDetails.notes); } documentation.WriteLine("== Functions =="); // Iterate all methods foreach (LuaFunction_Info method in api.functions) { // Grab the LuaApiFunction if it exists LuaApiFunction luaMethodDetails = method.Attribute; Logger.Log(Channel.Lua, "\t {0}", luaMethodDetails.name); documentation.WriteLine("=== {0} ===", luaMethodDetails.name); string functionSig = GetCleanFunctionSignature(method.MethodInfo, luaMethodDetails, luaApiDetails); documentation.WriteLine("<syntaxhighlight source lang=\"lua\">{0}</syntaxhighlight>", functionSig); bool hasParams = method.MethodInfo.GetParameters().Length != 0; if (hasParams) { documentation.WriteLine("'''Expected parameter types'''"); documentation.WriteLine("{| class=\"wikitable\""); } // Expected param types foreach (ParameterInfo param in method.MethodInfo.GetParameters()) { documentation.WriteLine("|-"); documentation.WriteLine("| {0} || {1}", param.Name, GetCleanTypeName(param.ParameterType)); } if (hasParams) { documentation.WriteLine("|}"); } documentation.WriteLine("'''Description''': {0}\n", luaMethodDetails.description); // Use custom return description if exists, else generate one documentation.WriteLine("'''Returns''': {0}\n", !string.IsNullOrEmpty(luaMethodDetails.returns) ? luaMethodDetails.returns : GetCleanTypeName(method.MethodInfo.ReturnType)); if (!string.IsNullOrEmpty(luaMethodDetails.notes)) { documentation.WriteLine("'''Notes''': {0}", luaMethodDetails.notes); } if (!string.IsNullOrEmpty(luaMethodDetails.warning)) { documentation.WriteLine("<span style=\"color:#ff0000\">'''Warning'''</span>: {0}", luaMethodDetails.warning); } if (!string.IsNullOrEmpty(luaMethodDetails.success)) { documentation.WriteLine("<span style=\"color:#009000\">'''Tip'''</span>: {0}", luaMethodDetails.success); } } bool wroteTitle = false; foreach (LuaVariableInfo fieldInfo in api.variables) { if (!wroteTitle) { documentation.WriteLine("== Variables =="); wroteTitle = true; } LuaApiVariable luaVariableDetails = fieldInfo.Attribute; documentation.WriteLine("=== {0} ===", luaVariableDetails.name); string varibleSig = string.Format("{0}.{1}", luaApiDetails.luaName, luaVariableDetails.name); documentation.WriteLine("<syntaxhighlight source lang=\"lua\">{0}</syntaxhighlight>", varibleSig); documentation.WriteLine("'''Description''': {0}\n", luaVariableDetails.description); } // Add time stamp documentation.WriteLine("\n\n'''Docs last hacked together on''': {0:dd/MM/yyyy H:mm}", DateTime.Now); documentation.Close(); } // TODO Enum docs string enumDocPath = string.Format("{0}/Constants.mediawiki", documentationPath); StreamWriter enumDocumentation = File.CreateText(enumDocPath); enumDocumentation.WriteLine("= Constants ="); enumDocumentation.WriteLine("== Enums =="); foreach (LuaEnumInfo enumInfo in GetAllEnums()) { enumDocumentation.WriteLine("=== {0} ===", enumInfo.Attribute.name); if (!string.IsNullOrEmpty(enumInfo.Attribute.description)) { enumDocumentation.WriteLine(enumInfo.Attribute.description); } enumDocumentation.WriteLine("{| class=\"wikitable\""); enumDocumentation.WriteLine("|-"); enumDocumentation.WriteLine("! Usage !! Description"); foreach (LuaEnumValueInfo value in enumInfo.values) { if (value.Attribute != null && value.Attribute.hidden) { continue; } enumDocumentation.WriteLine("|-"); enumDocumentation.WriteLine("| {0}.{1} || {2}", enumInfo.Attribute.name, value.StringValue, value.Attribute != null ? value.Attribute.description : string.Empty); } enumDocumentation.WriteLine("|}"); } enumDocumentation.Close(); } Logger.Log(Channel.Lua, "Completed Lua doc generation"); }