Merge pull request #4239 from ScottNZ/lua-new

Move to a managed Lua implementation
This commit is contained in:
Paul Chote
2013-12-06 02:37:04 -08:00
28 changed files with 178 additions and 165 deletions

View File

@@ -63,6 +63,12 @@
<Reference Include="FuzzyLogicLibrary">
<HintPath>..\thirdparty\FuzzyLogicLibrary.dll</HintPath>
</Reference>
<Reference Include="KopiLua">
<HintPath>..\thirdparty\KopiLua.dll</HintPath>
</Reference>
<Reference Include="NLua">
<HintPath>..\thirdparty\NLua.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
@@ -478,10 +484,6 @@
<Compile Include="Effects\Rank.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LuaInterface\LuaInterface.csproj">
<Project>{E915A0A4-2641-4F7E-8A88-8F123FA88BF1}</Project>
<Name>LuaInterface</Name>
</ProjectReference>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
<Project>{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}</Project>
<Name>OpenRA.FileFormats</Name>

View File

@@ -12,18 +12,23 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using LuaInterface;
using NLua;
using NLua.Event;
using OpenRA.FileFormats;
namespace OpenRA.Mods.RA.Scripting
{
public class LuaScriptContext : IDisposable
{
public Lua Lua { get; private set; }
readonly Cache<string, LuaFunction> functionCache;
public LuaScriptContext()
{
Log.Write("debug", "Creating Lua script context");
Lua = new Lua();
Lua.HookException += OnLuaException;
functionCache = new Cache<string, LuaFunction>(Lua.GetFunction);
}
public void RegisterObject(object target, string tableName, bool exposeAllMethods)
@@ -76,11 +81,21 @@ namespace OpenRA.Mods.RA.Scripting
}
}
void LogException(Exception e)
void OnLuaException(object sender, HookExceptionEventArgs e)
{
Game.Debug("{0}", e.Message);
ShowException(e.Exception);
}
void ShowException(Exception e)
{
ShowErrorMessage(e.Message, e.ToString());
}
public void ShowErrorMessage(string shortMessage, string longMessage)
{
Game.Debug("{0}", shortMessage);
Game.Debug("See debug.log for details");
Log.Write("debug", "{0}", e);
Log.Write("debug", "{0}", longMessage ?? shortMessage);
}
public void LoadLuaScripts(Func<string, string> getFileContents, params string[] files)
@@ -95,7 +110,7 @@ namespace OpenRA.Mods.RA.Scripting
}
catch (Exception e)
{
LogException(e);
ShowException(e);
}
}
}
@@ -104,14 +119,14 @@ namespace OpenRA.Mods.RA.Scripting
{
try
{
var function = Lua.GetFunction(name);
var function = functionCache[name];
if (function == null)
return null;
return function.Call(args);
}
catch (Exception e)
{
LogException(e);
ShowException(e);
return null;
}
}

View File

@@ -9,7 +9,6 @@
#endregion
using System;
using System.Collections.Generic;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Scripting

View File

@@ -8,16 +8,17 @@
*/
#endregion
using LuaInterface;
using System;
using System.Linq;
using NLua;
using OpenRA.Effects;
using OpenRA.FileFormats;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Air;
using OpenRA.Mods.RA.Missions;
using OpenRA.Scripting;
using OpenRA.Support;
using OpenRA.Traits;
using System;
using System.Linq;
using WorldRenderer = OpenRA.Graphics.WorldRenderer;
namespace OpenRA.Mods.RA.Scripting
@@ -43,7 +44,7 @@ namespace OpenRA.Mods.RA.Scripting
public void WorldLoaded(World w, WorldRenderer wr)
{
world = w;
AddMapActorGlobals();
context.Lua["World"] = w;
context.Lua["WorldRenderer"] = wr;
context.RegisterObject(this, "Internal", false);
@@ -55,22 +56,33 @@ namespace OpenRA.Mods.RA.Scripting
context.RegisterType(typeof(WRange), "WRange", true);
context.RegisterType(typeof(int2), "int2", true);
context.RegisterType(typeof(float2), "float2", true);
var sharedScripts = Game.modData.Manifest.LuaScripts ?? new string[0];
if (sharedScripts.Any())
context.LoadLuaScripts(f => FileSystem.Open(f).ReadAllText(), sharedScripts);
AddMapActorGlobals();
context.LoadLuaScripts(f => w.Map.Container.GetContent(f).ReadAllText(), info.LuaScripts);
context.InvokeLuaFunction("WorldLoaded");
}
void AddMapActorGlobals()
{
foreach (var kv in world.WorldActor.Trait<SpawnMapActors>().Actors)
context.Lua[kv.Key] = kv.Value;
{
if (context.Lua[kv.Key] != null)
context.ShowErrorMessage("{0}: The global name '{1}' is reserved and may not be used by map actor {2}".F(GetType().Name, kv.Key, kv.Value), null);
else
context.Lua[kv.Key] = kv.Value;
}
}
public void Tick(Actor self)
{
context.InvokeLuaFunction("Tick");
using (new PerfSample("tick_lua"))
context.InvokeLuaFunction("Tick");
}
[LuaGlobal]