mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 10:36:44 +00:00
Timers now use seconds instead of ms.
Append "Lib" to all libraries class names.
This commit is contained in:
parent
7c799426a9
commit
97161f0c85
21 changed files with 123 additions and 112 deletions
|
@ -51,7 +51,7 @@ local function draw()
|
|||
end
|
||||
|
||||
-- no idea why it's needed
|
||||
timer.sleep(1)
|
||||
timer.sleep(0)
|
||||
|
||||
draw()
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ local function melt()
|
|||
end
|
||||
gpu.setBuffer(buffer)
|
||||
|
||||
timer.delay(10):await()
|
||||
timer.delay(0):await()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -66,7 +66,7 @@ local function random()
|
|||
)
|
||||
end
|
||||
|
||||
timer.delay(100):await()
|
||||
timer.delay(0.1):await()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@ local machine = require("machine")
|
|||
|
||||
print("Goodbye!")
|
||||
|
||||
timer.sleep(1000)
|
||||
timer.sleep(1)
|
||||
|
||||
machine.reboot()
|
||||
|
|
|
@ -3,6 +3,6 @@ local machine = require("machine")
|
|||
|
||||
print("Goodbye!")
|
||||
|
||||
timer.sleep(1000)
|
||||
timer.sleep(1)
|
||||
|
||||
machine.shutdown()
|
||||
|
|
|
@ -5,7 +5,6 @@ local range = require("expect").range
|
|||
|
||||
function timer.sleep(n)
|
||||
expect(1, n, "number")
|
||||
range(1, 1)
|
||||
|
||||
local timerId = timer.start(n)
|
||||
repeat
|
||||
|
|
|
@ -21,7 +21,7 @@ local machine = require("machine")
|
|||
local audio = require("audio")
|
||||
local event = require("event")
|
||||
|
||||
local bootSleep = 2000
|
||||
local bootSleep = 2
|
||||
local bg = 0x0
|
||||
local fg = 0xffffff
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ public class Capy64 : Game, IGame
|
|||
public LuaState LuaRuntime { get; set; }
|
||||
public Eventing.EventEmitter EventEmitter { get; private set; }
|
||||
public DiscordIntegration Discord { get; set; }
|
||||
public int TickRate => tickrate;
|
||||
|
||||
public Color BorderColor { get; set; } = Color.Black;
|
||||
public Borders Borders = new()
|
||||
|
@ -106,7 +107,8 @@ public class Capy64 : Game, IGame
|
|||
private readonly GraphicsDeviceManager _graphics;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private ulong _totalTicks = 0;
|
||||
private ulong tickrate = 0;
|
||||
private int tickrate = 0;
|
||||
private int everyTick => 60 / tickrate;
|
||||
|
||||
public Capy64()
|
||||
{
|
||||
|
@ -274,7 +276,7 @@ public class Capy64 : Game, IGame
|
|||
{
|
||||
GameTime = gameTime,
|
||||
TotalTicks = _totalTicks,
|
||||
IsActiveTick = _totalTicks % (60 / tickrate) == 0,
|
||||
IsActiveTick = (int)_totalTicks % everyTick == 0,
|
||||
});
|
||||
|
||||
Drawing.End();
|
||||
|
|
|
@ -21,18 +21,18 @@ using static Capy64.Core.Audio;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
public class Audio : IComponent
|
||||
public class AudioLib : IComponent
|
||||
{
|
||||
private const int queueLimit = 8;
|
||||
|
||||
private static IGame _game;
|
||||
public Audio(IGame game)
|
||||
public AudioLib(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
_game.EventEmitter.OnClose += OnClose;
|
||||
}
|
||||
|
||||
private static readonly LuaRegister[] AudioLib = new LuaRegister[]
|
||||
private static readonly LuaRegister[] Library = new LuaRegister[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ public class Audio : IComponent
|
|||
private static int OpenLib(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
L.NewLib(AudioLib);
|
||||
L.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ using System;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
public class Event : IComponent
|
||||
public class EventLib : IComponent
|
||||
{
|
||||
private const int MaxPushQueue = 64;
|
||||
private static int PushQueue = 0;
|
||||
|
@ -30,12 +30,12 @@ public class Event : IComponent
|
|||
private static bool FrozenTaskAwaiter = false;
|
||||
|
||||
private static IGame _game;
|
||||
public Event(IGame game)
|
||||
public EventLib(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
}
|
||||
|
||||
private static readonly LuaRegister[] EventLib = new LuaRegister[]
|
||||
private static readonly LuaRegister[] Library = new LuaRegister[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ public class Event : IComponent
|
|||
private static int OpenLib(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
L.NewLib(EventLib);
|
||||
L.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -24,11 +24,11 @@ using System.Linq;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
public class FileSystem : IComponent
|
||||
public class FileSystemLib : IComponent
|
||||
{
|
||||
public static string DataPath = Path.Combine(Capy64.AppDataPath, "data");
|
||||
|
||||
public FileSystem()
|
||||
public FileSystemLib()
|
||||
{
|
||||
if (!Directory.Exists(DataPath))
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ public class FileSystem : IComponent
|
|||
}
|
||||
|
||||
// functions to add to the library, always end libraries with null
|
||||
private readonly LuaRegister[] FsLib = new LuaRegister[] {
|
||||
private readonly LuaRegister[] Library = new LuaRegister[] {
|
||||
new()
|
||||
{
|
||||
name = "list",
|
||||
|
@ -120,7 +120,7 @@ public class FileSystem : IComponent
|
|||
private int Open(IntPtr state)
|
||||
{
|
||||
var l = Lua.FromIntPtr(state);
|
||||
l.NewLib(FsLib);
|
||||
l.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -25,16 +25,16 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
public class GPU : IComponent
|
||||
public class GPULib : IComponent
|
||||
{
|
||||
|
||||
private static IGame _game;
|
||||
public GPU(IGame game)
|
||||
public GPULib(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
}
|
||||
|
||||
private readonly LuaRegister[] gpuLib = new LuaRegister[] {
|
||||
private readonly LuaRegister[] Library = new LuaRegister[] {
|
||||
new()
|
||||
{
|
||||
name = "getSize",
|
||||
|
@ -141,7 +141,7 @@ public class GPU : IComponent
|
|||
public int OpenLib(IntPtr state)
|
||||
{
|
||||
var l = Lua.FromIntPtr(state);
|
||||
l.NewLib(gpuLib);
|
||||
l.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -483,7 +483,7 @@ public class GPU : IComponent
|
|||
|
||||
var path = L.CheckString(1);
|
||||
|
||||
path = FileSystem.Resolve(path);
|
||||
path = FileSystemLib.Resolve(path);
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
|
@ -28,7 +28,7 @@ using System.Threading;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
#nullable enable
|
||||
public class HTTP : IComponent
|
||||
public class HTTPLib : IComponent
|
||||
{
|
||||
private static IGame _game;
|
||||
private static HttpClient _httpClient;
|
||||
|
@ -38,7 +38,7 @@ public class HTTP : IComponent
|
|||
public static readonly string UserAgent = $"Capy64/{Capy64.Version}";
|
||||
|
||||
private static IConfiguration _configuration;
|
||||
private readonly LuaRegister[] HttpLib = new LuaRegister[]
|
||||
private readonly LuaRegister[] Library = new LuaRegister[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ public class HTTP : IComponent
|
|||
},
|
||||
new(),
|
||||
};
|
||||
public HTTP(IGame game, IConfiguration configuration)
|
||||
public HTTPLib(IGame game, IConfiguration configuration)
|
||||
{
|
||||
_game = game;
|
||||
_requestId = 0;
|
||||
|
@ -75,7 +75,7 @@ public class HTTP : IComponent
|
|||
private int Open(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
L.NewLib(HttpLib);
|
||||
L.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -22,15 +22,15 @@ using System;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
public class Machine : IComponent
|
||||
public class MachineLib : IComponent
|
||||
{
|
||||
private static IGame _game;
|
||||
public Machine(IGame game)
|
||||
public MachineLib(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
}
|
||||
|
||||
private static readonly LuaRegister[] MachineLib = new LuaRegister[]
|
||||
private static readonly LuaRegister[] Library = new LuaRegister[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
|
@ -83,7 +83,7 @@ public class Machine : IComponent
|
|||
private static int OpenLib(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
L.NewLib(MachineLib);
|
||||
L.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -19,17 +19,17 @@ using System.Net.Sockets;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
public class TCP : IComponent
|
||||
public class TCPLib : IComponent
|
||||
{
|
||||
private static int Counter = 0;
|
||||
private static IGame _game;
|
||||
public TCP(IGame game)
|
||||
public TCPLib(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
Counter = 0;
|
||||
}
|
||||
|
||||
private static readonly LuaRegister[] TCPLib = new LuaRegister[]
|
||||
private static readonly LuaRegister[] Library = new LuaRegister[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ public class TCP : IComponent
|
|||
public int OpenLib(nint state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
L.NewLib(TCPLib);
|
||||
L.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ using static Capy64.Utils;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
internal class Term : IComponent
|
||||
internal class TermLib : IComponent
|
||||
{
|
||||
private struct Char
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ internal class Term : IComponent
|
|||
private static bool cursorState = false;
|
||||
private static bool enableCursor = true;
|
||||
private static Texture2D cursorTexture;
|
||||
public Term(IGame game)
|
||||
public TermLib(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
|
||||
|
@ -72,7 +72,7 @@ internal class Term : IComponent
|
|||
_game.EventEmitter.OnScreenSizeChange += OnScreenSizeChange;
|
||||
}
|
||||
|
||||
private readonly LuaRegister[] TermLib = new LuaRegister[]
|
||||
private readonly LuaRegister[] Library = new LuaRegister[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
|
@ -170,7 +170,7 @@ internal class Term : IComponent
|
|||
public int Open(IntPtr state)
|
||||
{
|
||||
var l = Lua.FromIntPtr(state);
|
||||
l.NewLib(TermLib);
|
||||
l.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -21,9 +21,15 @@ using System.Collections.Concurrent;
|
|||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
class Timer : IComponent
|
||||
class TimerLib : IComponent
|
||||
{
|
||||
private readonly LuaRegister[] TimerLib = new LuaRegister[]
|
||||
public class Timer
|
||||
{
|
||||
public int RemainingTicks = 0;
|
||||
public TaskMeta.RuntimeTask? Task;
|
||||
}
|
||||
|
||||
private readonly LuaRegister[] Library = new LuaRegister[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
|
@ -47,22 +53,51 @@ class Timer : IComponent
|
|||
private static IGame _game;
|
||||
private static uint _timerId = 0;
|
||||
|
||||
private static readonly ConcurrentDictionary<uint, System.Timers.Timer> timers = new();
|
||||
public Timer(IGame game)
|
||||
private static readonly ConcurrentDictionary<uint, Timer> timers = new();
|
||||
public TimerLib(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
|
||||
_game.EventEmitter.OnTick += OnTick;
|
||||
}
|
||||
|
||||
private void OnTick(object sender, Eventing.Events.TickEvent e)
|
||||
{
|
||||
if (e.IsActiveTick)
|
||||
{
|
||||
foreach (var t in timers)
|
||||
{
|
||||
var timer = t.Value;
|
||||
timer.RemainingTicks--;
|
||||
if (timer.RemainingTicks <= 0)
|
||||
{
|
||||
if (timer.Task == null)
|
||||
{
|
||||
_game.LuaRuntime.QueueEvent("timer", lk =>
|
||||
{
|
||||
lk.PushInteger(t.Key);
|
||||
|
||||
return 1;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
timer.Task.Fulfill(lk =>
|
||||
{
|
||||
lk.PushInteger(t.Key);
|
||||
});
|
||||
}
|
||||
|
||||
timers.TryRemove(t.Key, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LuaInit(Lua state)
|
||||
{
|
||||
_timerId = 0;
|
||||
|
||||
foreach (var pair in timers)
|
||||
{
|
||||
pair.Value.Stop();
|
||||
pair.Value.Dispose();
|
||||
}
|
||||
|
||||
timers.Clear();
|
||||
|
||||
state.RequireF("timer", Open, false);
|
||||
|
@ -71,36 +106,23 @@ class Timer : IComponent
|
|||
private int Open(IntPtr state)
|
||||
{
|
||||
var l = Lua.FromIntPtr(state);
|
||||
l.NewLib(TimerLib);
|
||||
l.NewLib(Library);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static int L_StartTimer(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var delay = L.CheckNumber(1);
|
||||
L.ArgumentCheck(delay > 0, 1, "delay must be greater than 0");
|
||||
|
||||
var timerId = _timerId++;
|
||||
var timer = new System.Timers.Timer
|
||||
|
||||
timers[timerId] = new Timer
|
||||
{
|
||||
AutoReset = false,
|
||||
Enabled = true,
|
||||
Interval = delay,
|
||||
};
|
||||
|
||||
timers[timerId] = timer;
|
||||
|
||||
timer.Elapsed += (o, e) =>
|
||||
{
|
||||
_game.LuaRuntime.QueueEvent("timer", lk =>
|
||||
{
|
||||
lk.PushInteger(timerId);
|
||||
|
||||
return 1;
|
||||
});
|
||||
timers.TryRemove(timerId, out _);
|
||||
RemainingTicks = (int)(delay * Capy64.Instance.TickRate)
|
||||
};
|
||||
|
||||
L.PushInteger(timerId);
|
||||
|
@ -112,27 +134,15 @@ class Timer : IComponent
|
|||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var delay = L.CheckNumber(1);
|
||||
L.ArgumentCheck(delay > 0, 1, "delay must be greater than 0");
|
||||
|
||||
var task = TaskMeta.Push(L, "timer");
|
||||
|
||||
var timerId = _timerId++;
|
||||
var timer = new System.Timers.Timer
|
||||
{
|
||||
AutoReset = false,
|
||||
Enabled = true,
|
||||
Interval = delay,
|
||||
};
|
||||
|
||||
timers[timerId] = timer;
|
||||
|
||||
timer.Elapsed += (o, e) =>
|
||||
timers[timerId] = new Timer
|
||||
{
|
||||
task.Fulfill(lk =>
|
||||
{
|
||||
lk.PushInteger(timerId);
|
||||
});
|
||||
timers.TryRemove(timerId, out _);
|
||||
RemainingTicks = (int)(delay * Capy64.Instance.TickRate),
|
||||
Task = task,
|
||||
};
|
||||
|
||||
return 1;
|
|
@ -255,7 +255,7 @@ public class TaskMeta : IComponent
|
|||
|
||||
private static void WaitForTask(Lua L)
|
||||
{
|
||||
L.PushCFunction(Libraries.Event.L_Pull);
|
||||
L.PushCFunction(Libraries.EventLib.L_Pull);
|
||||
L.PushString("task_finish");
|
||||
L.CallK(1, 4, 0, LK_Await);
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ public class WebSocketClient : IComponent
|
|||
});
|
||||
});
|
||||
|
||||
HTTP.WebSocketConnections.Remove(client);
|
||||
HTTPLib.WebSocketConnections.Remove(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,29 +25,29 @@ public class PanicScreen
|
|||
|
||||
public static void Render(string error, string details = null)
|
||||
{
|
||||
Term.ForegroundColor = ForegroundColor;
|
||||
Term.BackgroundColor = BackgroundColor;
|
||||
Term.SetCursorBlink(false);
|
||||
Term.SetSize(57, 23);
|
||||
Term.Clear();
|
||||
TermLib.ForegroundColor = ForegroundColor;
|
||||
TermLib.BackgroundColor = BackgroundColor;
|
||||
TermLib.SetCursorBlink(false);
|
||||
TermLib.SetSize(57, 23);
|
||||
TermLib.Clear();
|
||||
|
||||
var title = " Capy64 ";
|
||||
var halfX = (Term.Width / 2) + 1;
|
||||
Term.SetCursorPosition(halfX - (title.Length / 2), 2);
|
||||
Term.ForegroundColor = BackgroundColor;
|
||||
Term.BackgroundColor = ForegroundColor;
|
||||
Term.Write(title);
|
||||
var halfX = (TermLib.Width / 2) + 1;
|
||||
TermLib.SetCursorPosition(halfX - (title.Length / 2), 2);
|
||||
TermLib.ForegroundColor = BackgroundColor;
|
||||
TermLib.BackgroundColor = ForegroundColor;
|
||||
TermLib.Write(title);
|
||||
|
||||
Term.ForegroundColor = ForegroundColor;
|
||||
Term.BackgroundColor = BackgroundColor;
|
||||
Term.SetCursorPosition(1, 4);
|
||||
TermLib.ForegroundColor = ForegroundColor;
|
||||
TermLib.BackgroundColor = BackgroundColor;
|
||||
TermLib.SetCursorPosition(1, 4);
|
||||
Print(error + '\n');
|
||||
|
||||
if (details is not null)
|
||||
{
|
||||
Print(details);
|
||||
}
|
||||
Term.SetCursorPosition(1, 23);
|
||||
TermLib.SetCursorPosition(1, 23);
|
||||
Print("Hold CTRL + ALT + INSERT to reboot.");
|
||||
}
|
||||
|
||||
|
@ -55,12 +55,12 @@ public class PanicScreen
|
|||
{
|
||||
foreach (var ch in txt)
|
||||
{
|
||||
Term.Write(ch.ToString());
|
||||
if (Term.CursorPosition.X >= Term.Width || ch == '\n')
|
||||
TermLib.Write(ch.ToString());
|
||||
if (TermLib.CursorPosition.X >= TermLib.Width || ch == '\n')
|
||||
{
|
||||
Term.SetCursorPosition(1, (int)Term.CursorPosition.Y + 1);
|
||||
TermLib.SetCursorPosition(1, (int)TermLib.CursorPosition.Y + 1);
|
||||
}
|
||||
}
|
||||
Term.SetCursorPosition(1, (int)Term.CursorPosition.Y + 1);
|
||||
TermLib.SetCursorPosition(1, (int)TermLib.CursorPosition.Y + 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,12 +145,12 @@ internal class RuntimeManager : IComponent
|
|||
|
||||
emitter.Register();
|
||||
|
||||
if (!File.Exists(Path.Combine(FileSystem.DataPath, "init.lua")))
|
||||
if (!File.Exists(Path.Combine(FileSystemLib.DataPath, "init.lua")))
|
||||
{
|
||||
throw new LuaException("Operating System not found\nMissing init.lua");
|
||||
}
|
||||
|
||||
var initContent = File.ReadAllText(Path.Combine(FileSystem.DataPath, "init.lua"));
|
||||
var initContent = File.ReadAllText(Path.Combine(FileSystemLib.DataPath, "init.lua"));
|
||||
var status = luaState.Thread.LoadString(initContent, "=init.lua");
|
||||
if (status != LuaStatus.OK)
|
||||
{
|
||||
|
@ -180,14 +180,14 @@ internal class RuntimeManager : IComponent
|
|||
var installedFilePath = Path.Combine(Capy64.AppDataPath, ".installed");
|
||||
if (!File.Exists(installedFilePath) || force)
|
||||
{
|
||||
FileSystem.CopyDirectory("Assets/Lua/CapyOS", FileSystem.DataPath, true, true);
|
||||
FileSystemLib.CopyDirectory("Assets/Lua/CapyOS", FileSystemLib.DataPath, true, true);
|
||||
File.Create(installedFilePath).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static int L_OpenDataFolder(IntPtr state)
|
||||
{
|
||||
var path = FileSystem.DataPath;
|
||||
var path = FileSystemLib.DataPath;
|
||||
switch (Environment.OSVersion.Platform)
|
||||
{
|
||||
case PlatformID.Win32NT:
|
||||
|
|
|
@ -192,7 +192,7 @@ internal class Sandbox
|
|||
var errorMessage = new StringBuilder();
|
||||
foreach (var possiblePath in possiblePaths)
|
||||
{
|
||||
var path = FileSystem.Resolve(possiblePath);
|
||||
var path = FileSystemLib.Resolve(possiblePath);
|
||||
var info = new FileInfo(path);
|
||||
if (!info.Exists)
|
||||
{
|
||||
|
@ -229,7 +229,7 @@ internal class Sandbox
|
|||
bool hasMode = !L.IsNone(2);
|
||||
bool hasEnv = !L.IsNone(3);
|
||||
|
||||
var path = FileSystem.Resolve(filename);
|
||||
var path = FileSystemLib.Resolve(filename);
|
||||
|
||||
var fileInfo = new FileInfo(path);
|
||||
if (!fileInfo.Exists)
|
||||
|
|
Loading…
Reference in a new issue