Skip to content

Commit 408d6f7

Browse files
committed
New LuauScript and AirshipComponentV2 classes
1 parent 2cedf64 commit 408d6f7

File tree

8 files changed

+191
-45
lines changed

8 files changed

+191
-45
lines changed

Runtime/Code/Luau/AirshipComponent.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,7 @@ private static string CleanupFilePath(string path) {
610610
path += ".lua";
611611
}
612612

613-
path = path.ToLower();
614-
if (path.StartsWith("assets/", StringComparison.Ordinal)) {
613+
if (path.StartsWith("assets/", StringComparison.OrdinalIgnoreCase)) {
615614
path = path.Substring("assets/".Length);
616615
}
617616

@@ -703,7 +702,7 @@ public bool CreateThread() {
703702
// We only want one instance of airship components, so let's see if it already exists
704703
// in our require cache first.
705704
if (_isAirshipComponent) {
706-
var path = LuauCore.GetRequirePath(this, cleanPath);
705+
var path = LuauCore.GetRequirePath(scriptFile, cleanPath);
707706
var thread = LuauPlugin.LuauCreateThreadWithCachedModule(context, path, id);
708707

709708
// If thread exists, we've found the module and put it onto the top of the thread stack. Use
@@ -718,7 +717,7 @@ public bool CreateThread() {
718717
var gch = GCHandle.Alloc(this.scriptFile.m_bytes, GCHandleType.Pinned); //Ok
719718
var nativeCodegen = scriptFile.HasDirective("native");
720719

721-
m_thread = LuauPlugin.LuauCreateThread(context, gch.AddrOfPinnedObject(), scriptFile.m_bytes.Length, filenameStr, cleanPath.Length, id, nativeCodegen);
720+
m_thread = LuauPlugin.LuauCreateThread(context, scriptFile.m_bytes, cleanPath, id, nativeCodegen);
722721

723722
Marshal.FreeCoTaskMem(filenameStr);
724723
gch.Free();
@@ -748,7 +747,7 @@ public bool CreateThread() {
748747
} else {
749748
// Start airship component if applicable:
750749
if (_isAirshipComponent) {
751-
var path = LuauCore.GetRequirePath(this, cleanPath);
750+
var path = LuauCore.GetRequirePath(scriptFile, cleanPath);
752751
LuauPlugin.LuauCacheModuleOnThread(m_thread, path);
753752
InitializeAndAwakeAirshipComponent(m_thread, true);
754753
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using Luau;
3+
using UnityEngine;
4+
5+
public class AirshipComponentV2 : MonoBehaviour {
6+
public AirshipScript script;
7+
8+
public IntPtr thread;
9+
[HideInInspector] public LuauContext context = LuauContext.Game;
10+
11+
private void Awake() {
12+
// Load the component onto the thread:
13+
thread = LuauScript.LoadAndExecuteScript(gameObject, context, LuauScriptCacheMode.Cached, script);
14+
if (thread == IntPtr.Zero) {
15+
thread = LuauScript.LoadAndExecuteScript(gameObject, context, LuauScriptCacheMode.NotCached, script);
16+
}
17+
18+
if (thread == IntPtr.Zero) {
19+
// Failed to load the component
20+
Debug.LogError($"Component failed to load: {script.m_path}");
21+
return;
22+
}
23+
24+
print("AirshipComponentV2::Awake");
25+
}
26+
}

Runtime/Code/Luau/AirshipComponentV2.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Code/Luau/LuauCoreCallbacks.cs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,15 +1006,15 @@ private static bool FastGetAndWriteValueProperty(IntPtr thread, object objectRef
10061006
return false;
10071007
}
10081008

1009-
public static string GetRequirePath(AirshipComponent binding, string fileNameStr) {
1010-
if (binding != null) {
1009+
public static string GetRequirePath(AirshipScript script, string fileNameStr) {
1010+
if (script != null) {
10111011
if (fileNameStr.Contains("/") == false) {
10121012
//Get a stripped name
1013-
var fname = GetTidyPathNameForLuaFile(binding.m_fileFullPath);
1013+
var fname = GetTidyPathNameForLuaFile(script.m_path);
10141014
fileNameStr = fname;
10151015
} else if (fileNameStr.StartsWith("./")) {
10161016
//Get a stripped name
1017-
var fname = GetTidyPathNameForLuaFile(binding.m_fileFullPath);
1017+
var fname = GetTidyPathNameForLuaFile(script.m_path);
10181018

10191019
//Remove just this filename off the end
10201020
var bits = new List<string>(fname.Split("/"));
@@ -1023,7 +1023,7 @@ public static string GetRequirePath(AirshipComponent binding, string fileNameStr
10231023

10241024
fileNameStr = bindingPath + "/" + fileNameStr.Substring(2);
10251025
} else if (fileNameStr.StartsWith("../")) {
1026-
var fname = GetTidyPathNameForLuaFile(binding.m_fileFullPath);
1026+
var fname = GetTidyPathNameForLuaFile(script.m_path);
10271027

10281028
//Remove two bits of this filename off the end
10291029
var bits = new List<string>(fname.Split("/"));
@@ -1046,6 +1046,47 @@ public static string GetRequirePath(AirshipComponent binding, string fileNameStr
10461046

10471047
return fileNameStr;
10481048
}
1049+
1050+
// public static string GetRequirePath(AirshipComponent binding, string fileNameStr) {
1051+
// if (binding != null) {
1052+
// if (fileNameStr.Contains("/") == false) {
1053+
// //Get a stripped name
1054+
// var fname = GetTidyPathNameForLuaFile(binding.m_fileFullPath);
1055+
// fileNameStr = fname;
1056+
// } else if (fileNameStr.StartsWith("./")) {
1057+
// //Get a stripped name
1058+
// var fname = GetTidyPathNameForLuaFile(binding.m_fileFullPath);
1059+
//
1060+
// //Remove just this filename off the end
1061+
// var bits = new List<string>(fname.Split("/"));
1062+
// bits.RemoveAt(bits.Count - 1);
1063+
// var bindingPath = Path.Combine(bits.ToArray());
1064+
//
1065+
// fileNameStr = bindingPath + "/" + fileNameStr.Substring(2);
1066+
// } else if (fileNameStr.StartsWith("../")) {
1067+
// var fname = GetTidyPathNameForLuaFile(binding.m_fileFullPath);
1068+
//
1069+
// //Remove two bits of this filename off the end
1070+
// var bits = new List<string>(fname.Split("/"));
1071+
// if (bits.Count > 0) {
1072+
// bits.RemoveAt(bits.Count - 1);
1073+
// }
1074+
//
1075+
// if (bits.Count > 0) {
1076+
// bits.RemoveAt(bits.Count - 1);
1077+
// }
1078+
//
1079+
// var bindingPath = Path.Combine(bits.ToArray());
1080+
//
1081+
// fileNameStr = bindingPath + "/" + fileNameStr.Substring(2);
1082+
// }
1083+
// }
1084+
//
1085+
// //Fully qualify it
1086+
// fileNameStr = GetTidyPathNameForLuaFile(fileNameStr);
1087+
//
1088+
// return fileNameStr;
1089+
// }
10491090

10501091
//Take a random path name from a require and transform it into its path relative to /assets/.
10511092
//The same file always gets the same path, so this is used as a key to return the same table every time from lua land
@@ -1056,7 +1097,7 @@ static unsafe int RequirePathCallback(LuauContext context, IntPtr thread, IntPtr
10561097
var fileNameStr = LuauCore.PtrToStringUTF8(fileName, fileNameSize);
10571098

10581099
LuauState.FromContext(context).TryGetScriptBindingFromThread(thread, out var binding);
1059-
var fileRequirePath = GetRequirePath(binding, fileNameStr);
1100+
var fileRequirePath = GetRequirePath(binding.scriptFile, fileNameStr);
10601101

10611102
LuauCore.WritePropertyToThread(thread, fileRequirePath, typeof(string));
10621103

Runtime/Code/Luau/LuauPlugin.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Diagnostics;
66
using System.Runtime.CompilerServices;
77
using System.Runtime.InteropServices;
8+
using System.Text;
89
using UnityEngine;
910
using System.Threading;
1011
using Luau;
@@ -466,11 +467,22 @@ public static void LuauDestroySignals(LuauContext context, IntPtr thread, int un
466467
[DllImport("LuauPlugin")]
467468
#endif
468469
private static extern IntPtr CreateThread(LuauContext context, IntPtr script, int scriptLength, IntPtr filename, int filenameLength, int gameObjectId, bool nativeCodegen);
469-
public static IntPtr LuauCreateThread(LuauContext context, IntPtr script, int scriptLength, IntPtr filename, int filenameLength, int gameObjectId, bool nativeCodegen) {
470+
public static IntPtr LuauCreateThread(LuauContext context, byte[] scriptBytecode, string filename, int gameObjectId, bool nativeCodegen) {
470471
ThreadSafetyCheck();
471472
BeginExecutionCheck(CurrentCaller.CreateThread);
472-
IntPtr returnValue = CreateThread(context, script, scriptLength, filename, filenameLength, gameObjectId, nativeCodegen);
473+
474+
var scriptBytecodeHandle = GCHandle.Alloc(scriptBytecode, GCHandleType.Pinned);
475+
var scriptBytecodePtr = scriptBytecodeHandle.AddrOfPinnedObject();
476+
477+
var filenameBytes = Encoding.UTF8.GetBytes(filename);
478+
var filenameLength = Encoding.UTF8.GetByteCount(filename);
479+
var filenameHandle = GCHandle.Alloc(filenameBytes, GCHandleType.Pinned);
480+
var filenamePtr = filenameHandle.AddrOfPinnedObject();
481+
482+
var returnValue = CreateThread(context, scriptBytecodePtr, scriptBytecode.Length, filenamePtr, filenameLength, gameObjectId, nativeCodegen);
483+
473484
EndExecutionCheck();
485+
474486
return returnValue;
475487
}
476488

Runtime/Code/Luau/LuauScript.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using System;
2+
using System.IO;
3+
using Luau;
4+
using UnityEngine;
5+
6+
public enum LuauScriptCacheMode {
7+
NotCached,
8+
Cached,
9+
}
10+
11+
[LuauAPI(LuauContext.Protected)]
12+
public class LuauScript : MonoBehaviour {
13+
public AirshipScript script;
14+
15+
public IntPtr thread;
16+
[HideInInspector] public LuauContext context = LuauContext.Game;
17+
18+
private static string CleanupFilePath(string path) {
19+
var extension = Path.GetExtension(path);
20+
if (extension == string.Empty) {
21+
path += ".lua";
22+
}
23+
24+
if (path.StartsWith("assets/", StringComparison.OrdinalIgnoreCase)) {
25+
path = path.Substring("assets/".Length);
26+
}
27+
28+
return path;
29+
}
30+
31+
private void Awake() {
32+
LoadAndExecuteScript(gameObject, context, LuauScriptCacheMode.NotCached, script);
33+
}
34+
35+
/// <summary>
36+
/// Creates a new Luau thread from the given script. The thread is not yet executed. Returns a nullptr if the Luau
37+
/// fails to create the new thread.
38+
/// </summary>
39+
public static IntPtr LoadScript(GameObject obj, LuauContext context, LuauScriptCacheMode cacheMode, AirshipScript script) {
40+
if (ReferenceEquals(script, null)) {
41+
throw new Exception("[LuauScript]: Script reference is null");
42+
}
43+
44+
if (!script.m_compiled) {
45+
throw new Exception($"[LuauScript]: Script reference cannot run due to compilation error: {script.m_compilationError}");
46+
}
47+
48+
var cleanPath = CleanupFilePath(script.m_path);
49+
var id = ThreadDataManager.GetOrCreateObjectId(obj);
50+
var nativeCodegen = script.HasDirective("native");
51+
52+
// Tell Luau to load the bytecode onto a new Luau thread:
53+
switch (cacheMode) {
54+
case LuauScriptCacheMode.NotCached:
55+
return LuauPlugin.LuauCreateThread(context, script.m_bytes, cleanPath, id, nativeCodegen);
56+
case LuauScriptCacheMode.Cached:
57+
var requirePath = LuauCore.GetRequirePath(script, cleanPath);
58+
return LuauPlugin.LuauCreateThreadWithCachedModule(context, requirePath, id);
59+
default:
60+
throw new Exception($"[LuauScript]: Unhandled mode: {cacheMode}");
61+
}
62+
}
63+
64+
/// <summary>
65+
/// Execute a thread. The thread must first be created with the LoadScript function.
66+
/// </summary>
67+
public static void ExecuteScript(IntPtr thread) {
68+
// Execute the new thread. We don't need to do anything after this. If the thread errors, the error will be
69+
// outputted. If the thread yields, whoever yielded it owns responsibility for resuming it (e.g. the task
70+
// scheduler):
71+
LuauPlugin.LuauRunThread(thread);
72+
}
73+
74+
/// <summary>
75+
/// Loads and executes the given script. The executed Luau thread is returned. If the thread is a nullptr, then
76+
/// that indicates that Luau failed to load the script.
77+
/// </summary>
78+
public static IntPtr LoadAndExecuteScript(GameObject obj, LuauContext context, LuauScriptCacheMode cacheMode, AirshipScript script) {
79+
var thread = LoadScript(obj, context, cacheMode, script);
80+
81+
// A nullptr indicates that Luau failed to load the bytecode. Luau will write the error to the output, and we
82+
// need to check for the nullptr and stop here:
83+
if (thread == IntPtr.Zero) {
84+
if (cacheMode == LuauScriptCacheMode.NotCached) {
85+
Debug.LogError($"[LuauScript] Failed to create Luau thread for script: {script.m_path}");
86+
}
87+
return thread;
88+
}
89+
90+
ExecuteScript(thread);
91+
92+
return thread;
93+
}
94+
}

Runtime/Code/Luau/LuauScript.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Prefabs/LuauCore.prefab

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,37 +57,6 @@ MonoBehaviour:
5757
m_Script: {fileID: 11500000, guid: abf698a3782d4e57873f696052179bdb, type: 3}
5858
m_Name:
5959
m_EditorClassIdentifier:
60-
--- !u!1 &6032594285117304591
61-
GameObject:
62-
m_ObjectHideFlags: 0
63-
m_CorrespondingSourceObject: {fileID: 0}
64-
m_PrefabInstance: {fileID: 0}
65-
m_PrefabAsset: {fileID: 0}
66-
serializedVersion: 6
67-
m_Component:
68-
- component: {fileID: 2257238983143894783}
69-
m_Layer: 0
70-
m_Name: LuauModules
71-
m_TagString: Untagged
72-
m_Icon: {fileID: 0}
73-
m_NavMeshLayer: 0
74-
m_StaticEditorFlags: 0
75-
m_IsActive: 1
76-
--- !u!4 &2257238983143894783
77-
Transform:
78-
m_ObjectHideFlags: 0
79-
m_CorrespondingSourceObject: {fileID: 0}
80-
m_PrefabInstance: {fileID: 0}
81-
m_PrefabAsset: {fileID: 0}
82-
m_GameObject: {fileID: 6032594285117304591}
83-
serializedVersion: 2
84-
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
85-
m_LocalPosition: {x: 0, y: 0, z: 0}
86-
m_LocalScale: {x: 1, y: 1, z: 1}
87-
m_ConstrainProportionsScale: 0
88-
m_Children: []
89-
m_Father: {fileID: 6517521483168823064}
90-
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
9160
--- !u!1 &7196551055182178265
9261
GameObject:
9362
m_ObjectHideFlags: 0
@@ -121,7 +90,6 @@ Transform:
12190
m_Children:
12291
- {fileID: 3215400887442349911}
12392
- {fileID: 9206524290973728886}
124-
- {fileID: 2257238983143894783}
12593
m_Father: {fileID: 0}
12694
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
12795
--- !u!114 &7912692223461348264

0 commit comments

Comments
 (0)