1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-13 05:44:11 +02:00
Beef/IDE/src/Compiler/CompilerBase.bf
2022-05-02 08:57:41 -07:00

219 lines
6.3 KiB
Beef

using System;
using System.Collections;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using Beefy.utils;
using Beefy;
using System.IO;
using IDE.util;
namespace IDE.Compiler
{
public abstract class CompilerBase : CommandQueueManager
{
public enum ViewRefreshKind
{
None,
Collapse,
FullRefresh
}
public int32 mResolveAllWait;
protected List<String> mQueuedOutput = new List<String>() ~ DeleteContainerAndItems!(_);
public ViewRefreshKind mWantsActiveViewRefresh;
public volatile int32 mThreadYieldCount = 0; // Whether our thread wants to be yielded to, and for how many ticks
protected class ResolveAllCommand : Command
{
}
protected class ProjectSourceRemovedCommand : Command
{
public ProjectSource mProjectSource;
public ~this()
{
mProjectSource.ReleaseRef();
}
}
protected class ProjectSourceCommand : Command
{
public ProjectSource mProjectSource;
public IdSpan mSourceCharIdData ~ _.Dispose();
public String mSourceString ~ delete _;
public SourceHash mSourceHash;
}
protected class CompileCommand : Command
{
public String mOutputDirectory ~ delete _;
}
public void QueueCompile(String outputDirectory)
{
CompileCommand command = new CompileCommand();
command.mOutputDirectory = new String(outputDirectory);
QueueCommand(command);
}
public void QueueDeferredResolveAll()
{
mResolveAllWait = 2;
}
public virtual void QueueProjectSource(ProjectSource projectSource, SourceHash sourceHash, bool wantsHash)
{
ProjectSourceCommand command = new ProjectSourceCommand();
command.mProjectSource = projectSource;
command.mSourceString = new String();
var wantsHash;
IDEApp.sApp.FindProjectSourceContent(projectSource, out command.mSourceCharIdData, false, command.mSourceString, wantsHash ? &command.mSourceHash : null);
if (!(sourceHash case .None))
{
if (command.mSourceHash != sourceHash)
projectSource.mWasBuiltWithOldHash = true;
command.mSourceHash = sourceHash;
}
if (gApp.mBfBuildCompiler == this)
{
if (gApp.mDbgVersionedCompileDir != null)
{
String fileName = scope .();
projectSource.GetFullImportPath(fileName);
String baseSrcDir = scope .();
baseSrcDir.Append(projectSource.mProject.mProjectDir);
baseSrcDir.Append(@"\src\");
if (fileName.StartsWith(baseSrcDir, .OrdinalIgnoreCase))
{
fileName.Remove(0, baseSrcDir.Length - 1);
fileName.Insert(0, projectSource.mProject.mProjectName);
}
//Console.WriteLine("Hey!");
fileName.Replace('\\', '_');
fileName.Replace('/', '_');
String path = scope .();
path.Append(gApp.mDbgVersionedCompileDir);
path.Append(fileName);
//Utils.WriteTextFile(path, command.mSourceString);
var filePath = scope String();
projectSource.GetFullImportPath(filePath);
String contents = scope .();
contents.AppendF("//@{}|{}\n", filePath, File.GetLastWriteTime(filePath).GetValueOrDefault().ToFileTime());
contents.Append(command.mSourceString);
File.WriteAllText(path, contents);
}
}
QueueCommand(command);
}
public virtual void ClearQueuedProjectSource()
{
using (mMonitor.Enter())
{
// Don't remove the head of the queue because we may already be processing it
for (int32 i = 1; i < mCommandQueue.Count; i++)
{
if (mCommandQueue[i] is ProjectSourceCommand)
{
mCommandQueue.RemoveAt(i);
i--;
}
}
}
}
public void QueueProjectSourceRemoved(ProjectSource projectSource)
{
ProjectSourceRemovedCommand command = new ProjectSourceRemovedCommand();
command.mProjectSource = projectSource;
projectSource.AddRef();
QueueCommand(command);
}
public bool HasResolvedAll()
{
return (!HasQueuedCommands()) && (mResolveAllWait == 0);
}
public void QueueResolveCommand()
{
ResolveAllCommand command = new ResolveAllCommand();
QueueCommand(command);
}
public override void ProcessQueue()
{
mThreadYieldCount = 0;
DoProcessQueue();
}
public override void Update()
{
if (!ThreadRunning)
{
CheckThreadDone();
if (mWantsActiveViewRefresh != .None)
{
IDEApp.sApp.RefreshVisibleViews(null, mWantsActiveViewRefresh);
mWantsActiveViewRefresh = .None;
}
if (mThreadYieldCount > 0)
{
mThreadYieldCount--;
}
else if (mAllowThreadStart)
{
if (mResolveAllWait > 0)
{
if (--mResolveAllWait == 0)
{
QueueResolveCommand();
}
}
if (mCommandQueue.Count > 0)
{
StartQueueProcessThread();
}
}
}
}
public bool PopMessage(String outMessage)
{
using (mMonitor.Enter())
{
if (mQueuedOutput.Count > 0)
{
String msg = mQueuedOutput[0];
mQueuedOutput.RemoveAt(0);
msg.MoveTo(outMessage);
delete msg;
return true;
}
}
return false;
}
public void ClearMessages()
{
using (mMonitor.Enter())
{
ClearAndDeleteItems(mQueuedOutput);
}
}
}
}