using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Tango.PPC.Browser.Attributes;
using Tango.PPC.Browser.Views;
using Tango.PPC.Common.Helpers;
using Tango.Touch.Keyboard;
namespace Tango.PPC.Browser.BoundsObjects
{
[BoundObject("keyboard", "keyboard.js")]
public class KeyboardHandler
{
private DateTime _lastTime;
public KeyboardHandler()
{
_lastTime = DateTime.Now;
}
public void openKeyboard(String inputType)
{
if pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Tango.Core.Helpers;
using Tango.Core.IO;
using Tango.Logging;
namespace Tango.Protobuf
{
/// <summary>
/// Represents a protobuf compiler base class.
/// </summary>
/// <seealso cref="Tango.Protobuf.IProtoCompiler" />
public abstract class ProtoCompiler : IProtoCompiler
{
private const String COMPILERS_FOLDER_NAME = "ProtoCompilers"; //Compilers folder name.
protected String _compilersPath; //Compilers folder path.
private LogManager logManager = LogManager.Default;
private int _currentProgress;
private int _totalProgress;
/// <summary>
/// Occurs when the compiler has made some progress.
/// </summary>
public event EventHandler<CompilerProgressEventArgs> CompilationProgress;
/// <summary>
/// Gets the compiler language.
/// </summary>
public abstract CompilerLanguage Language { get; }
/// <summary>
/// Gets the proto imports folders.
/// </summary>
public List<String> ImportsFolders { get; private set; }
/// <summary>
/// Gets a value indicating whether this compiler uses the default folder structure when generating code.
/// </summary>
public virtual bool UsesDefaultStructure { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ProtoCompiler"/> class.
/// </summary>
public ProtoCompiler()
{
ImportsFolders = new List<string>();
_compilersPath = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), COMPILERS_FOLDER_NAME);
}
/// <summary>
/// Compiles the specified .proto message file.
/// </summary>
/// <param name="inputFile">.proto file to compile</param>
/// <returns>
/// A list of compiled results.
/// </returns>
public virtual IEnumerable<CompilerFileResult> CompileFile(string inputFile)
{
logManager.Log("Compiling file " + inputFile);
CompilationProgress?.Invoke(this, new CompilerProgressEventArgs()
{
Current = _currentProgress++,
Total = _totalProgress,
File = inputFile,
});
var tmpPath = TemporaryManager.Default.CreateFolder();
logManager.Log("Temp path: " + tmpPath);
String importsString = "--proto_path \"" + Path.GetDirectoryName(inputFile) + "\" ";
logManager.Log("Added import string: " + importsString);
foreach (var path in ImportsFolders)
{
String importStr = "--proto_path \"" + path + "\" ";
importsString += importStr;
logManager.Log("Added import string: " + importStr);
}
Process p = new Process();
logManager.Log("Compilers folder path: " + _compilersPath);
p.StartInfo.WorkingDirectory = _compilersPath;
String oldCurrentDirectory = Environment.CurrentDirectory;
Environment.CurrentDirectory = _compilersPath;
p.StartInfo.FileName = GetProtoCompilerName();
logManager.Log("Protobuf executable path: " + p.StartInfo.FileName);
p.StartInfo.Arguments = String.Format(
"{0} {1}=\"{2}\" \"{3}\"",
importsString,
GetProtoArguments(),
tmpPath,
inputFile);
logManager.Log("Final arguments:\n" + p.StartInfo.Arguments);
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
logManager.Log("Executing compilation...");
p.Start();
p.WaitForExit(5000);
Environment.CurrentDirectory = oldCurrentDirectory;
String error = p.StandardError.ReadToEnd();
if (!String.IsNullOrWhiteSpace(error))
{
var lines = error.Split(new[] { '\r', '\n' });
throw logManager.Log(new CompilerException() { Issues = lines.Where(x => x.Length > 0).ToList() });
}
List<CompilerFileResult> results = new List<CompilerFileResult>();
foreach (var file in Directory.GetFiles(tmpPath, "*.*", SearchOption.AllDirectories))
{
CompilerFileResult result = new CompilerFileResult(Language, inputFile, Path.GetFileName(file), Path.GetDirectoryName(file).Replace(tmpPath, "").TrimStart('\\', '\\'), File.ReadAllText(file));
results.Add(result);
}
if (tmpPath.Delete())
{
logManager.Log("Removed temp path: " + tmpPath);
}
else
{
logManager.Log("Could not remove temp path: " + tmpPath);
}
logManager.Log(Path.GetFileName(inputFile) + "compiled!");
return results;
}
/// <summary>
/// Compiles the specified .proto message file asynchronously.
/// </summary>
/// <param name="inputFile">.proto file to compile</param>
/// <returns>
/// A list of compiled results.
/// </returns>
public async Task<IEnumerable<CompilerFileResult>> CompileFileAsync(string inputFile)
{
return await new Task<IEnumerable<CompilerFileResult>>(() => { return CompileFile(inputFile); });
}
/// <summary>
/// Compiles all files in the specified folder recursively.
/// </summary>
/// <param name="sourceFolder">The source folder</param>
/// <returns>
/// Compilation result.
/// </returns>
public virtual CompilerFolderResult CompileFolder(string sourceFolder, params String[] includeFolders)
{
_currentProgress = 0;
_totalProgress = Directory.GetFiles(sourceFolder, "*.proto", SearchOption.AllDirectories).Length;
if (!UsesDefaultStructure)
{
logManager.Log("Compiling folder: " + sourceFolder);
ImportsFolders.Clear();
ImportsFolders.AddRange(Directory.GetDirectories(sourceFolder, "*.*", SearchOption.AllDirectories));
var result = CompileFolder(sourceFolder, sourceFolder);
logManager.Log(Path.GetFileName(sourceFolder) + "compiled!");
return OnPostProcessFolderCompilation(result);
}
else
{
return CompileFolderDefault(sourceFolder);
}
}
/// <summary>
/// Compiles all files in the specified folder recursively.
/// </summary>
/// <param name="sourceFolder">The source folder</param>
/// <returns>
/// Compilation result.
/// </returns>
protected virtual CompilerFolderResult CompileFolder(string rootFolder, string sourceFolder)
{
List<ICompilerResult> currentFolderResults = new List<ICompilerResult>();
CompilerFolderResult currentFolder = new CompilerFolderResult(currentFolderResults, Language, sourceFolder, sourceFolder.Replace(rootFolder, ""));
foreach (String file in Directory.GetFiles(sourceFolder, "*.proto"))
{
currentFolderResults.AddRange(CompileFile(file));
}
foreach (string folder in Directory.GetDirectories(sourceFolder))
{
if (Directory.GetFiles(folder, "*.proto").Length > 0)
{
currentFolderResults.Add(CompileFolder(rootFolder, folder));
}
}
return currentFolder;
}
/// <summary>
/// Compiles all files in the specified folder recursively and asynchronously.
/// </summary>
/// <param name="sourceFolder">The source folder</param>
/// <returns>
/// Compilation result.
/// </returns>
public async Task<CompilerFolderResult> CompileFolderAsync(string sourceFolder)
{
return await new Task<CompilerFolderResult>(() => { return CompileFolder(sourceFolder); });
}
/// <summary>
/// Compiles all files in the specified folder recursively using the default structure.
/// </summary>
/// <param name="sourceFolder">The source folder</param>
/// <returns>
/// Compilation result.
/// </returns>
private CompilerFolderResult CompileFolderDefault(string sourceFolder)
{
logManager.Log("Compiling folder: " + sourceFolder);
Dictionary<string, CompilerFileResult> fileResults = new Dictionary<string, CompilerFileResult>();
ImportsFolders.Clear();
ImportsFolders.AddRange(Directory.GetDirectories(sourceFolder, "*.*", SearchOption.AllDirectories));
var tempPath = TemporaryManager.Default.CreateFolder();
foreach (var file in Directory.GetFiles(sourceFolder, "*.proto", SearchOption.AllDirectories))
{
foreach (var fileResult in CompileFile(file))
{
String targetFolder = Path.Combine(tempPath, fileResult.RelativePath);
String targetFile = Path.Combine(targetFolder, fileResult.Name);
Directory.CreateDirectory(targetFolder);
File.WriteAllText(targetFile, fileResult.Content);
fileResults.Add(targetFile, fileResult);
}
}
var result = CompileFolderDefault(tempPath, tempPath, fileResults);
tempPath.Delete();
logManager.Log(Path.GetFileName(sourceFolder) + "compiled!");
return OnPostProcessFolderCompilation(result);
}
/// <summary>
/// Compiles all files in the specified folder recursively using the default structure.
/// </summary>
/// <param name="rootFolder"></param>
/// <param name="sourceFolder">The source folder</param>
/// <returns>
/// Compilation result.
/// </returns>
private CompilerFolderResult CompileFolderDefault(string rootFolder, string sourceFolder, Dictionary<string, CompilerFileResult> fileResults)
{
List<ICompilerResult> currentFolderResults = new List<ICompilerResult>();
CompilerFolderResult currentFolder = new CompilerFolderResult(currentFolderResults, Language, sourceFolder, Path.GetFileName(sourceFolder));
foreach (String file in Directory.GetFiles(sourceFolder, "*.*"))
{
currentFolderResults.Add(fileResults[file]);
}
foreach (string folder in Directory.GetDirectories(sourceFolder))
{
currentFolderResults.Add(CompileFolderDefault(rootFolder, folder, fileResults));
}
return currentFolder;
}
/// <summary>
/// Override in order to manipulate the folder compilation result.
/// </summary>
/// <param name="result">The result.</param>
/// <returns></returns>
protected virtual CompilerFolderResult OnPostProcessFolderCompilation(CompilerFolderResult result)
{
return result;
}
/// <summary>
/// Gets the protobuf compiler CLI arguments (without input/output files!).
/// </summary>
/// <returns></returns>
protected abstract String GetProtoArguments();
/// <summary>
/// Gets the protobuf compiler CLI file name (override when using a compiler other than the default 'protoc.exe').
/// </summary>
/// <remarks>
/// The compiler program must be located in the compilers folder.
/// </remarks>
/// <returns></returns>
protected virtual String GetProtoCompilerName()
{
return "protoc.exe";
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
//TODO: Dispose...
}
}
}