Skip to content

Commit

Permalink
fix descriptor binding error
Browse files Browse the repository at this point in the history
  • Loading branch information
egokb committed Dec 20, 2024
1 parent 4b74d4f commit 9406085
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 301 deletions.
11 changes: 4 additions & 7 deletions src/ContextGenerator/BindingContextGenerator.Template.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,21 @@
public partial class BindingContextGenerator
{
#region 类模板
const string DefaultNamespace = "__DataBindingGenerated";

/// <summary>
/// 构建绑定上下文
/// </summary>
public static string BuildContextCode(ContextBindingInfo contextInfo, string usings, string @namespace, string converters, string bindings, string unbindings, string functions)
public static string BuildContextCode(ContextBindingInfo contextInfo, string converters, string bindings, string unbindings, string functions)
{
return $$"""
{{Utility.FileHead}}
{{usings}}
namespace {{@namespace}}
namespace {{Utility.BindingContextDefaultNamespace}}
{
[FUI.ViewModelAttribute(typeof({{contextInfo.viewModelType}}))]
[FUI.ViewAttribute("{{contextInfo.viewName}}")]
public class __{{contextInfo.viewModelType.ToCSharpName()}}_{{contextInfo.viewName}}_Binding_Generated : FUI.BindingContext
public class {{contextInfo.viewModelType.ToCSharpName()}}_{{contextInfo.viewName}}_Binding_Generated : FUI.BindingContext
{
{{converters}}
public __{{contextInfo.viewModelType.ToCSharpName()}}_{{contextInfo.viewName}}_Binding_Generated(FUI.IView view, FUI.Bindable.ObservableObject viewModel) : base(view, viewModel) { }
public {{contextInfo.viewModelType.ToCSharpName()}}_{{contextInfo.viewName}}_Binding_Generated(FUI.IView view, FUI.Bindable.ObservableObject viewModel) : base(view, viewModel) { }
protected override void Binding()
{
Expand Down
33 changes: 1 addition & 32 deletions src/ContextGenerator/BindingContextGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ internal IReadOnlyList<Source> Generate(IReadOnlyList<ContextBindingInfo> contex
var result = new List<Source>();
foreach (var bindingContext in contexts)
{
var usings = new List<string>(0);
var @namespace = string.Empty;

var bindingBuilder = new StringBuilder();
var unbindingBuilder = new StringBuilder();
HashSet<string> converterTypes = new HashSet<string>();
Expand Down Expand Up @@ -65,15 +62,8 @@ internal IReadOnlyList<Source> Generate(IReadOnlyList<ContextBindingInfo> contex
var convertersBuilder = new StringBuilder();
BuildConverterCostructor(converterTypes, ref convertersBuilder);

//添加using
var usingBuilder = new StringBuilder();
BuildUsings(usings, ref usingBuilder);

//添加Namespace
var @namespaceName = string.IsNullOrEmpty(@namespace) ? DefaultNamespace : @namespace;

//组装所有的绑定代码
var code = BuildContextCode(bindingContext, usingBuilder.ToString(), @namespaceName, convertersBuilder.ToString(), bindingBuilder.ToString(), unbindingBuilder.ToString(), functionBuilder.ToString());
var code = BuildContextCode(bindingContext, convertersBuilder.ToString(), bindingBuilder.ToString(), unbindingBuilder.ToString(), functionBuilder.ToString());

//格式化代码
code = Utility.NormalizeCode(code);
Expand Down Expand Up @@ -148,27 +138,6 @@ void BuildConverterCostructor(HashSet<string> converterTypes, ref StringBuilder
}
}

//构造所有的using
void BuildUsings(IEnumerable<string> usings, ref StringBuilder usingBuilder)
{
if (usings == null)
{
usingBuilder.AppendLine("");
}
else
{
foreach (var @using in usings)
{
if (string.IsNullOrEmpty(@using))
{
continue;
}

usingBuilder.AppendLine($"using {@using};");
}
}
}

/// <summary>
/// 生成从View到ViewModel的绑定代码和解绑代码
/// </summary>
Expand Down
5 changes: 2 additions & 3 deletions src/ContextInfoGenerator/ContextInfoByAttributeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,13 @@ PropertyBindingInfo CreatePropertyBindingInfo(SemanticModel semanticModel, Class
PropertyInfo CreatePropertyInfo(SemanticModel semanticModel, ClassDeclarationSyntax clazz, PropertyDeclarationSyntax property, AttributeSyntax attribute)
{
var propertyName = property.Identifier.Text;
var propertyType = semanticModel.GetTypeInfo(property).Type;
var isList = Utility.IsObservableList(clazz, property);
var propertyType = semanticModel.GetTypeInfo(property.Type).Type;

return new PropertyInfo
{
name = propertyName,
type = propertyType.ToString(),
isList = isList,
isList = propertyType.IsObservableList(),
location = property.GetLocation().ToLocationInfo(),
};
}
Expand Down
4 changes: 0 additions & 4 deletions src/ContextInfoGenerator/ContextInfoByDescriptorGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ public List<ContextBindingInfo> Generate(SemanticModel semanticModel, SyntaxNode
foreach (var classDeclaration in classDeclarations)
{
var classType = semanticModel.GetDeclaredSymbol(classDeclaration);
if(classType.ToString() == "Test.Descriptor.TestDescriptorContextDescriptor")
{
var a = 0;
}
if(!classType.IsContextDescriptor(out var viewModelType))
{
continue;
Expand Down
5 changes: 3 additions & 2 deletions src/ContextInfoGenerator/ContextInfoGenerators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ internal async Task<IReadOnlyList<ContextBindingInfo>> Generate(Project project,
/// <param name="output">输出文件夹</param>
void TrySaveToFile(ContextBindingInfo info, string output)
{
if (!string.IsNullOrEmpty(output))
if (string.IsNullOrEmpty(output))
{
return;
}
Expand All @@ -87,7 +87,8 @@ void TrySaveToFile(ContextBindingInfo info, string output)
}

var json = Newtonsoft.Json.JsonConvert.SerializeObject(info, Newtonsoft.Json.Formatting.Indented);
var fileName = $"{Utility.GetBindingContextTypeName(info)}.binding";
//这个文件名要保持和上下文类型的全名一致 以便于后续根据上下文类型查找对应的绑定信息
var fileName = $"{Utility.GetBindingContextTypeFullName(info)}.binding";
var file = Path.Combine(output, fileName);
File.WriteAllText(file, json);
}
Expand Down
5 changes: 5 additions & 0 deletions src/FUIStubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ public class CommandAttribute : Attribute { }
public interface IValueConverter { }

public interface IValueConverter<T1, T2> { }

public interface ISynchronizeProperties
{
void Synchronize();
}
}

namespace FUI.BindingDescriptor
Expand Down
179 changes: 179 additions & 0 deletions src/PipeServer/MessageClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
using System.IO.Pipes;

namespace FUICompiler
{
internal class MessageClient : IDisposable
{
const string PipeName = "FUICompilerMessage";
const int BufferSize = 1024;
readonly NamedPipeClientStream pipeClient;
readonly Queue<byte[]> sendQueue = new Queue<byte[]>();
readonly CancellationTokenSource cts = new CancellationTokenSource();

public event Action<byte[]> MessageReceived;
public event Action Connected;
public event Action Disconnected;

static MessageClient instance;

public static MessageClient Instance
{
get
{
if (instance == null)
{
instance = new MessageClient();
}

return instance;
}
}

MessageClient()
{
pipeClient = new NamedPipeClientStream(".", PipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
}

public async Task ConnectAsync(int timeoutMs = 5000)
{
if (IsConnected)
{
return;
}

try
{
await pipeClient.ConnectAsync(timeoutMs, cts.Token);
Connected?.Invoke();

// 启动读写任务
_ = ReadMessagesAsync();
_ = ProcessSendQueueAsync();
}
catch (Exception)
{
throw;
}
}

public void Send(byte[] bytes)
{
if (!IsConnected)
{
throw new InvalidOperationException("未连接到服务器");
}

lock (sendQueue)
{
sendQueue.Enqueue(bytes);
}
}

async Task ReadMessagesAsync()
{
var buffer = new byte[BufferSize];

try
{
while (IsConnected && !cts.Token.IsCancellationRequested)
{
var message = new List<byte>();
do
{
var bytesRead = await pipeClient.ReadAsync(buffer, 0, buffer.Length, cts.Token);
if (bytesRead == 0)
{
break;
}

for (int i = 0; i < bytesRead; i++)
{
message.Add(buffer[i]);
}
}
while (!pipeClient.IsMessageComplete);

MessageReceived?.Invoke(message.ToArray());
}
}
catch (IOException)
{
// 服务端断开连接
HandleDisconnection();
}
catch (OperationCanceledException)
{
// 正常取消
}
}

async Task ProcessSendQueueAsync()
{
try
{
while (IsConnected && !cts.Token.IsCancellationRequested)
{
byte[] message = null;

lock (sendQueue)
{
if (sendQueue.Count > 0)
{
message = sendQueue.Dequeue();
}
}

if (message != null)
{
await pipeClient.WriteAsync(message, 0, message.Length, cts.Token);
await pipeClient.FlushAsync(cts.Token);
}
else
{
await Task.Delay(100, cts.Token); // 避免空轮询
}
}
}
catch (IOException)
{
// 服务端断开连接
HandleDisconnection();
}
catch (OperationCanceledException)
{
// 正常取消
}
}

void HandleDisconnection()
{
if (!IsConnected)
{
return;
}

Disconnected?.Invoke();
}

public void Disconnect()
{
if (!IsConnected)
{
return;
}

cts.Cancel();
pipeClient.Close();
Disconnected?.Invoke();
}

public void Dispose()
{
Disconnect();
cts.Dispose();
pipeClient.Dispose();
}

public bool IsConnected => pipeClient.IsConnected;
}
}
32 changes: 0 additions & 32 deletions src/PipeServer/Server.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

try
{
string workspace = "..\\..\\..\\..\\..\\..\\FUI\\";
args = $"--sln={workspace}.\\FUI.sln --project=FUI.Test --output={workspace}.\\Library\\ScriptAssemblies --binding={workspace}.\\Binding\\ --generated={workspace}.\\FUI\\Generated\\ --ctx_type=Mix --binding_output={workspace}.\\FUI\\BindingInfo\\".Split(' ');
//string workspace = "..\\..\\..\\..\\..\\..\\FUI\\";
//args = $"--sln={workspace}.\\FUI.sln --project=FUI.Test --output={workspace}.\\Library\\ScriptAssemblies --binding={workspace}.\\Binding\\ --generated={workspace}.\\FUI\\Generated\\ --ctx_type=Mix --binding_output={workspace}.\\FUI\\BindingInfo\\".Split(' ');
var param = ParseArgs(args);
var compiler = new Compiler(param);
await compiler.Build();
Expand Down
Loading

0 comments on commit 9406085

Please sign in to comment.