public void Help(string command) { if (_functions.Contains(command)) { LuaFunctionDescriptor func = (LuaFunctionDescriptor)_functions[command]; Console.WriteLine(func.FunctionFullDocumentation); return; } if (command.IndexOf(".") == -1) { if (_packages.ContainsKey(command)) { LuaPackageDescriptor pkg = (LuaPackageDescriptor)_packages[command]; Console.WriteLine(pkg.WriteHelp(command)); return; } else { Console.WriteLine("No such function or package: " + command); return; } } string[] parts = command.Split('.'); if (!_packages.ContainsKey(parts[0])) { Console.WriteLine("No such function or package: " + command); return; } LuaPackageDescriptor desc = (LuaPackageDescriptor)_packages[parts[0]]; if (!desc.HasFunction(parts[1])) { Console.WriteLine("Package " + parts[0] + " doesn't have a " + parts[1] + " function."); return; } Console.WriteLine(desc.WriteHelp(parts[1])); }
/// <summary> /// Registers the Lua-attributed functions in the target object. /// </summary> /// <param name="target">The target to load Lua-attributed functions from.</param> /// <param name="package">The package to register the functions under.</param> /// <param name="packageDocumentation">The documentation for the package.</param> public void RegisterLuaFunctions(object target, string package, string packageDocumentation) { // Sanity checks if (target == null || _lua == null || _functions == null || _packages == null) { return; } try { LuaPackageDescriptor pPackage = null; Console.WriteLine("Loading Lua library: " + target.ToString()); if (package != null) { // Check if the package already exists if (!_packages.ContainsKey("package")) { // Create a new package _lua.DoString(package + " = {}"); pPackage = new LuaPackageDescriptor(package, packageDocumentation); } else // Access the old package { pPackage = (LuaPackageDescriptor)_packages["package"]; } } // Get the target type Type targetType = target.GetType(); // ... and simply iterate through all its methods foreach (MethodInfo info in targetType.GetMethods()) { // ... then through all this method's attributes foreach (Attribute attr in Attribute.GetCustomAttributes(info)) { // ... and if they happen to be one of our LuaFunctionAttribute attributes if (attr.GetType() == typeof(LuaFunctionAttribute)) { LuaFunctionAttribute luaAttr = (LuaFunctionAttribute)attr; ArrayList paramList = new ArrayList(); ArrayList paramDocs = new ArrayList(); // Get the desired function name and doc string, along with parameter info string fName = luaAttr.FunctionName; string fDoc = luaAttr.FunctionDocumentation; string[] pDocs = luaAttr.FunctionParameters; // Now get the expected parameters from the MethodInfo object ParameterInfo[] pInfo = info.GetParameters(); // If they don't match, someone forgot to add some documentation to the // attribute, complain and go to the next method if (pDocs != null && (pInfo.Length != pDocs.Length)) { Console.WriteLine("Function " + info.Name + " (exported as " + fName + ") argument number mismatch. Declared " + pDocs.Length + " but requires " + pInfo.Length + "."); break; } // Build a parameter <-> parameter doc hashtable for (int i = 0; i < pInfo.Length; i++) { paramList.Add(pInfo[i].Name); paramDocs.Add(pDocs[i]); } // Get a new function descriptor from this information LuaFunctionDescriptor func = new LuaFunctionDescriptor(fName, fDoc, paramList, paramDocs); if (pPackage != null) { // Check if the package already contains the function if (!pPackage.Functions.ContainsKey(fName)) { // Add the new package function pPackage.AddFunction(func); _lua.RegisterFunction(package + fName, target, info); _lua.DoString(package + "." + fName + " = " + package + fName); _lua.DoString(package + fName + " = nil"); } } else { // Check if the function has already been loaded if (!_functions.ContainsKey(fName)) { // Add it to the global hashtable _functions.Add(fName, func); // And tell the VM to register it _lua.RegisterFunction(fName, target, info); } } } } } if (pPackage != null && !_packages.ContainsKey(package)) { _packages.Add(package, pPackage); } } catch (Exception e) { } finally { } }