修改库名为 YwxAppWpfBarrage

This commit is contained in:
yangwx01
2025-03-29 19:54:02 +08:00
parent 07479c8c6b
commit 72ae1ece9f
191 changed files with 2078 additions and 379 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,95 @@
{
"Version": 1,
"WorkspaceRootPath": "D:\\repos\\YwxAppWpfDanMu\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}|YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj|d:\\repos\\ywxappwpfdanmu\\ywxappwpfdanmu\\ywxappwpfbarrage.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|",
"RelativeMoniker": "D:0:0:{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}|YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj|solutionrelative:ywxappwpfdanmu\\ywxappwpfbarrage.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|"
},
{
"AbsoluteMoniker": "D:0:0:{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}|YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj|d:\\repos\\ywxappwpfdanmu\\ywxappwpfdanmu\\ywxappwpfbarrage.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|",
"RelativeMoniker": "D:0:0:{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}|YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj|solutionrelative:ywxappwpfdanmu\\ywxappwpfbarrage.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|"
},
{
"AbsoluteMoniker": "D:0:0:{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}|YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj|d:\\repos\\ywxappwpfdanmu\\ywxappwpfdanmu\\services\\barrageperformancemonitor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}|YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj|solutionrelative:ywxappwpfdanmu\\services\\barrageperformancemonitor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}|YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj|d:\\repos\\ywxappwpfdanmu\\ywxappwpfdanmu\\assemblyinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}|YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj|solutionrelative:ywxappwpfdanmu\\assemblyinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 323,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "YwxAppWpfBarrage",
"DocumentMoniker": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj",
"RelativeDocumentMoniker": "YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj",
"ToolTip": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj",
"RelativeToolTip": "YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
"WhenOpened": "2025-03-29T11:48:09.045Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "YwxAppWpfBarrage",
"DocumentMoniker": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj",
"RelativeDocumentMoniker": "YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj",
"ToolTip": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj",
"RelativeToolTip": "YwxAppWpfDanMu\\YwxAppWpfBarrage.csproj",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAAAiAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
"WhenOpened": "2025-03-29T11:47:00.615Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "BarragePerformanceMonitor.cs",
"DocumentMoniker": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\Services\\BarragePerformanceMonitor.cs",
"RelativeDocumentMoniker": "YwxAppWpfDanMu\\Services\\BarragePerformanceMonitor.cs",
"ToolTip": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\Services\\BarragePerformanceMonitor.cs",
"RelativeToolTip": "YwxAppWpfDanMu\\Services\\BarragePerformanceMonitor.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAQAAAAaAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-03-29T11:44:42.999Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "AssemblyInfo.cs",
"DocumentMoniker": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\AssemblyInfo.cs",
"RelativeDocumentMoniker": "YwxAppWpfDanMu\\AssemblyInfo.cs",
"ToolTip": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\AssemblyInfo.cs",
"RelativeToolTip": "YwxAppWpfDanMu\\AssemblyInfo.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAwAAAAtAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-03-29T11:43:51.574Z",
"EditorCaption": ""
}
]
}
]
}
]
}

View File

@@ -18,10 +18,6 @@
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,31 +0,0 @@
{
"Version": 1,
"WorkspaceRootPath": "D:\\repos\\YwxAppWpfDanMu\\",
"Documents": [],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 323,
"SelectedChildIndex": -1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
}
]
}
]
}
]
}

View File

@@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:danmu="clr-namespace:YwxAppWpfDanMu.Controls;assembly=YwxAppWpfDanMu"
xmlns:danmu="clr-namespace:YwxAppWpfBarrage.Controls;assembly=YwxAppWpfBarrage"
mc:Ignorable="d"
Title="弹幕演示" Height="450" Width="800">
<Grid>
@@ -16,7 +16,7 @@
<RowDefinition Height="7*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<danmu:DanMuControl x:Name="DanMuControl" Grid.Row="0" LineCount="10" />
<danmu:BarrageControl x:Name="BarrageControl" Grid.Row="0" LineCount="10" />
</Grid>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="暂停" Width="80" Margin="5" Click="PauseButton_Click"/>

View File

@@ -1,9 +1,9 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using YwxAppWpfDanMu;
using YwxAppWpfDanMu.Controls;
using YwxAppWpfDanMu.Models;
using YwxAppWpfBarrage;
using YwxAppWpfBarrage.Controls;
using YwxAppWpfBarrage.Models;
namespace WpfApp1;
@@ -19,61 +19,61 @@ public partial class MainWindow : Window
InitializeComponent();
// 订阅事件
DanMuControl.DanMuClick += OnDanMuClick;
DanMuControl.DanMuAdded += OnDanMuAdded;
DanMuControl.DanMuRemoved += OnDanMuRemoved;
BarrageControl.BarrageClick += OnBarrageClick;
BarrageControl.BarrageAdded += OnBarrageAdded;
BarrageControl.BarrageRemoved += OnBarrageRemoved;
}
private void OnDanMuClick(object sender, DanMuEventArgs e)
private void OnBarrageClick(object sender, BarrageEventArgs e)
{
MessageBox.Show($"点击了弹幕: {e.Message.Content}");
}
private void OnDanMuAdded(object sender, DanMuEventArgs e)
private void OnBarrageAdded(object sender, BarrageEventArgs e)
{
// 可以在这里处理弹幕添加事件
}
private void OnDanMuRemoved(object sender, DanMuEventArgs e)
private void OnBarrageRemoved(object sender, BarrageEventArgs e)
{
// 可以在这里处理弹幕移除事件
}
private void PauseButton_Click(object sender, RoutedEventArgs e)
{
DanMuControl.IsPaused = true;
BarrageControl.IsPaused = true;
}
private void ResumeButton_Click(object sender, RoutedEventArgs e)
{
DanMuControl.IsPaused = false;
BarrageControl.IsPaused = false;
}
private void ClearButton_Click(object sender, RoutedEventArgs e)
{
DanMuControl.ClearAll();
BarrageControl.ClearAll();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// 方法1: 添加单条弹幕
AddSingleTestDanMu();
AddSingleTestBarrage();
// 方法2: 添加多条弹幕(批量)
// AddMultipleTestDanMu(5);
// AddMultipleTestBarrage(5);
}
// 添加单条测试弹幕
private void AddSingleTestDanMu()
private void AddSingleTestBarrage()
{
var colors = new[] { Colors.Red, Colors.Green, Colors.Blue, Colors.Yellow, Colors.White, Colors.Cyan, Colors.Magenta };
var fonts = new[] { "Microsoft YaHei", "SimSun", "Arial", "Segoe UI" };
var message = new DanMuMessage
var message = new BarrageMessage
{
// Content = $"这是单条测试弹幕 {DateTime.Now:HH:mm:ss}",
Content = $"这是单条测试弹幕 ",
@@ -85,19 +85,19 @@ public partial class MainWindow : Window
// Opacity = 0.7 + _random.NextDouble() * 0.3,
AvatarUrl = "https://unpkg.com/outeres@0.0.10/demo/avatar/1.jpg" // 使用占位图作为头像
};
DanMuControl.AddDanMu(message);
BarrageControl.AddBarrage(message);
}
// 添加多条测试弹幕
private void AddMultipleTestDanMu(int count)
private void AddMultipleTestBarrage(int count)
{
var messages = new List<DanMuMessage>();
var messages = new List<BarrageMessage>();
var colors = new[] { Colors.Red, Colors.Green, Colors.Blue, Colors.Yellow, Colors.White, Colors.Cyan, Colors.Magenta };
var fonts = new[] { "Microsoft YaHei", "SimSun", "Arial", "Segoe UI" };
for (int i = 0; i < count; i++)
{
messages.Add(new DanMuMessage
messages.Add(new BarrageMessage
{
Content = $"批量测试弹幕 {i + 1} - {DateTime.Now:HH:mm:ss}",
Color = colors[_random.Next(colors.Length)],
@@ -110,6 +110,6 @@ public partial class MainWindow : Window
});
}
DanMuControl.AddDanMuBatch(messages);
BarrageControl.AddBarrageBatch(messages);
}
}

View File

@@ -20,7 +20,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\YwxAppWpfDanMu\YwxAppWpfDanMu.csproj" />
<ProjectReference Include="..\YwxAppWpfBarrage\YwxAppWpfBarrage.csproj" />
</ItemGroup>
<ItemGroup>

View File

@@ -61,7 +61,7 @@ namespace WpfApp1 {
return;
}
_contentLoaded = true;
System.Uri resourceLocater = new System.Uri("/WpfApp1;component/mainwindow.xaml", System.UriKind.Relative);
System.Uri resourceLocater = new System.Uri("/WpfApp1;V1.0.0.0;component/mainwindow.xaml", System.UriKind.Relative);
#line 1 "..\..\..\MainWindow.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("WpfApp1")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+07479c8c6b5d1bc1a226e3f92169457cefc591c0")]
[assembly: System.Reflection.AssemblyProductAttribute("WpfApp1")]
[assembly: System.Reflection.AssemblyTitleAttribute("WpfApp1")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
// 由 MSBuild WriteCodeFragment 类生成。

View File

@@ -0,0 +1 @@
5870e39427d95ecaf95f3e7f0d2696bd9ded97099c3d61bcee307afeed84777f

View File

@@ -0,0 +1,16 @@
is_global = true
build_property.TargetFramework = net8.0-windows
build_property.TargetPlatformMinVersion = 7.0
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = WpfApp1
build_property.ProjectDir = D:\repos\YwxAppWpfBarrage\WpfApp1\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle = 8.0
build_property.EnableCodeStyleSeverity =

View File

@@ -0,0 +1,71 @@
#pragma checksum "..\..\..\App.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "DCC59813AB95D23CF72F07367E2D9621042BF6D9"
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Controls.Ribbon;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Shell;
using WpfApp1;
namespace WpfApp1 {
/// <summary>
/// App
/// </summary>
public partial class App : System.Windows.Application {
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "9.0.3.0")]
public void InitializeComponent() {
#line 5 "..\..\..\App.xaml"
this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
#line default
#line hidden
}
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "9.0.3.0")]
public static void Main() {
WpfApp1.App app = new WpfApp1.App();
app.InitializeComponent();
app.Run();
}
}
}

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("WpfApp1")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+07479c8c6b5d1bc1a226e3f92169457cefc591c0")]
[assembly: System.Reflection.AssemblyProductAttribute("WpfApp1")]
[assembly: System.Reflection.AssemblyTitleAttribute("WpfApp1")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
// 由 MSBuild WriteCodeFragment 类生成。

View File

@@ -0,0 +1 @@
29dbf76db50ae405a4c1163e544ff28dfe0654e089379128e7499a0c5aa0a08b

View File

@@ -0,0 +1,16 @@
is_global = true
build_property.TargetFramework = net8.0-windows
build_property.TargetPlatformMinVersion = 7.0
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = WpfApp1
build_property.ProjectDir = D:\repos\YwxAppWpfDanMu\WpfApp1\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle = 8.0
build_property.EnableCodeStyleSeverity =

View File

@@ -1,17 +1,17 @@
{
"format": 1,
"restore": {
"D:\\repos\\YwxAppWpfDanMu\\WpfApp1\\WpfApp1.csproj": {}
"D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\WpfApp1.csproj": {}
},
"projects": {
"D:\\repos\\YwxAppWpfDanMu\\WpfApp1\\WpfApp1.csproj": {
"D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\WpfApp1.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "D:\\repos\\YwxAppWpfDanMu\\WpfApp1\\WpfApp1.csproj",
"projectUniqueName": "D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\WpfApp1.csproj",
"projectName": "WpfApp1",
"projectPath": "D:\\repos\\YwxAppWpfDanMu\\WpfApp1\\WpfApp1.csproj",
"projectPath": "D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\WpfApp1.csproj",
"packagesPath": "C:\\Users\\shiy7\\.nuget\\packages\\",
"outputPath": "D:\\repos\\YwxAppWpfDanMu\\WpfApp1\\obj\\",
"outputPath": "D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
@@ -32,8 +32,8 @@
"net8.0-windows7.0": {
"targetAlias": "net8.0-windows",
"projectReferences": {
"D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj": {
"projectPath": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj"
"D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj": {
"projectPath": "D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj"
}
}
}
@@ -75,74 +75,6 @@
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201/PortableRuntimeIdentifierGraph.json"
}
}
},
"D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj",
"projectName": "YwxAppWpfDanMu",
"projectPath": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj",
"packagesPath": "C:\\Users\\shiy7\\.nuget\\packages\\",
"outputPath": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\shiy7\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"net8.0-windows"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net8.0-windows7.0": {
"targetAlias": "net8.0-windows",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.200"
},
"frameworks": {
"net8.0-windows7.0": {
"targetAlias": "net8.0-windows",
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
},
"Microsoft.WindowsDesktop.App.WPF": {
"privateAssets": "none"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201/PortableRuntimeIdentifierGraph.json"
}
}
}
}
}

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">False</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>

View File

@@ -1,32 +1,12 @@
{
"version": 3,
"targets": {
"net8.0-windows7.0": {
"YwxAppWpfDanMu/1.0.0": {
"type": "project",
"framework": ".NETCoreApp,Version=v8.0",
"compile": {
"bin/placeholder/YwxAppWpfDanMu.dll": {}
},
"runtime": {
"bin/placeholder/YwxAppWpfDanMu.dll": {}
},
"frameworkReferences": [
"Microsoft.WindowsDesktop.App.WPF"
]
}
}
},
"libraries": {
"YwxAppWpfDanMu/1.0.0": {
"type": "project",
"path": "../YwxAppWpfDanMu/YwxAppWpfDanMu.csproj",
"msbuildProject": "../YwxAppWpfDanMu/YwxAppWpfDanMu.csproj"
}
"net8.0-windows7.0": {}
},
"libraries": {},
"projectFileDependencyGroups": {
"net8.0-windows7.0": [
"YwxAppWpfDanMu >= 1.0.0"
"D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj"
]
},
"packageFolders": {
@@ -36,11 +16,11 @@
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "D:\\repos\\YwxAppWpfDanMu\\WpfApp1\\WpfApp1.csproj",
"projectUniqueName": "D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\WpfApp1.csproj",
"projectName": "WpfApp1",
"projectPath": "D:\\repos\\YwxAppWpfDanMu\\WpfApp1\\WpfApp1.csproj",
"projectPath": "D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\WpfApp1.csproj",
"packagesPath": "C:\\Users\\shiy7\\.nuget\\packages\\",
"outputPath": "D:\\repos\\YwxAppWpfDanMu\\WpfApp1\\obj\\",
"outputPath": "D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
@@ -61,8 +41,8 @@
"net8.0-windows7.0": {
"targetAlias": "net8.0-windows",
"projectReferences": {
"D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj": {
"projectPath": "D:\\repos\\YwxAppWpfDanMu\\YwxAppWpfDanMu\\YwxAppWpfDanMu.csproj"
"D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj": {
"projectPath": "D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj"
}
}
}
@@ -104,5 +84,16 @@
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.201/PortableRuntimeIdentifierGraph.json"
}
}
}
},
"logs": [
{
"code": "NU1105",
"level": "Error",
"message": "找不到“D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj”的项目信息。如果使用 Visual Studio这可能是因为该项目已被卸载或不属于当前解决方案因此请从命令行运行还原。否则项目文件可能无效或缺少还原所需的目标。",
"libraryId": "D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj",
"targetGraphs": [
"net8.0-windows7.0"
]
}
]
}

View File

@@ -0,0 +1,18 @@
{
"version": 2,
"dgSpecHash": "YlqQWizSB44=",
"success": false,
"projectFilePath": "D:\\repos\\YwxAppWpfBarrage\\WpfApp1\\WpfApp1.csproj",
"expectedPackageFiles": [],
"logs": [
{
"code": "NU1105",
"level": "Error",
"message": "找不到“D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj”的项目信息。如果使用 Visual Studio这可能是因为该项目已被卸载或不属于当前解决方案因此请从命令行运行还原。否则项目文件可能无效或缺少还原所需的目标。",
"libraryId": "D:\\repos\\YwxAppWpfBarrage\\YwxAppWpfBarrage\\YwxAppWpfBarrage.csproj",
"targetGraphs": [
"net8.0-windows7.0"
]
}
]
}

View File

@@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35828.75
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YwxAppWpfDanMu", "YwxAppWpfDanMu\YwxAppWpfDanMu.csproj", "{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApp1", "WpfApp1\WpfApp1.csproj", "{7605DAD6-FF29-68CC-A841-EC859FB1D9DB}"
EndProject
Global
@@ -13,10 +11,6 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BCBD427E-7D3C-4FE7-A49D-CE45517E84A9}.Release|Any CPU.Build.0 = Release|Any CPU
{7605DAD6-FF29-68CC-A841-EC859FB1D9DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7605DAD6-FF29-68CC-A841-EC859FB1D9DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7605DAD6-FF29-68CC-A841-EC859FB1D9DB}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@@ -10,7 +10,7 @@ using System.Windows;
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
[assembly: AssemblyDescription("A WPF DanMu (bullet comment) control library")]
[assembly: AssemblyDescription("A WPF Barrage (bullet comment) control library")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]

View File

@@ -1,9 +1,9 @@
<UserControl x:Class="YwxAppWpfDanMu.Controls.DanMuControl"
<UserControl x:Class="YwxAppWpfBarrage.Controls.BarrageControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Canvas x:Name="DanMuCanvas" Background="Transparent" ClipToBounds="True"/>
<Canvas x:Name="BarrageCanvas" Background="Transparent" ClipToBounds="True"/>
</UserControl>

View File

@@ -5,32 +5,32 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using YwxAppWpfDanMu.Models;
using YwxAppWpfDanMu.Services;
using YwxAppWpfDanMu.Utils;
using YwxAppWpfBarrage.Models;
using YwxAppWpfBarrage.Services;
using YwxAppWpfBarrage.Utils;
namespace YwxAppWpfDanMu.Controls
namespace YwxAppWpfBarrage.Controls
{
public partial class DanMuControl : UserControl
public partial class BarrageControl : UserControl
{
private readonly DanMuPool _danMuPool;
private readonly DanMuDispatcher _dispatcher;
private readonly DanMuQueueProcessor _queueProcessor;
private readonly BarragePool _danMuPool;
private readonly BarrageDispatcher _dispatcher;
private readonly BarrageQueueProcessor _queueProcessor;
private readonly RateLimiter _rateLimiter;
private readonly DanMuPerformanceMonitor _performanceMonitor;
private readonly BarragePerformanceMonitor _performanceMonitor;
internal List<DanMuTrack> _tracks = new List<DanMuTrack>();
private readonly Dictionary<DanMuItem, DanMuTrack> _activeItems = new Dictionary<DanMuItem, DanMuTrack>();
internal List<BarrageTrack> _tracks = new List<BarrageTrack>();
private readonly Dictionary<BarrageItem, BarrageTrack> _activeItems = new Dictionary<BarrageItem, BarrageTrack>();
public DanMuControl()
public BarrageControl()
{
InitializeComponent();
_danMuPool = new DanMuPool(this);
_dispatcher = new DanMuDispatcher(Dispatcher);
_queueProcessor = new DanMuQueueProcessor(_dispatcher);
_danMuPool = new BarragePool(this);
_dispatcher = new BarrageDispatcher(Dispatcher);
_queueProcessor = new BarrageQueueProcessor(_dispatcher);
_rateLimiter = new RateLimiter(50); // 限制每秒50条
_performanceMonitor = new DanMuPerformanceMonitor();
_performanceMonitor = new BarragePerformanceMonitor();
Loaded += OnLoaded;
Unloaded += OnUnloaded;
@@ -40,7 +40,7 @@ namespace YwxAppWpfDanMu.Controls
#region Dependency Properties
public static readonly DependencyProperty LineCountProperty = DependencyProperty.Register(
"LineCount", typeof(int), typeof(DanMuControl), new PropertyMetadata(5, OnLineCountChanged));
"LineCount", typeof(int), typeof(BarrageControl), new PropertyMetadata(5, OnLineCountChanged));
public int LineCount
{
@@ -49,7 +49,7 @@ namespace YwxAppWpfDanMu.Controls
}
public static readonly DependencyProperty IsPausedProperty = DependencyProperty.Register(
"IsPaused", typeof(bool), typeof(DanMuControl), new PropertyMetadata(false));
"IsPaused", typeof(bool), typeof(BarrageControl), new PropertyMetadata(false));
public bool IsPaused
{
@@ -61,15 +61,15 @@ namespace YwxAppWpfDanMu.Controls
#region Events
public event EventHandler<DanMuEventArgs> DanMuClick;
public event EventHandler<DanMuEventArgs> DanMuAdded;
public event EventHandler<DanMuEventArgs> DanMuRemoved;
public event EventHandler<BarrageEventArgs> BarrageClick;
public event EventHandler<BarrageEventArgs> BarrageAdded;
public event EventHandler<BarrageEventArgs> BarrageRemoved;
#endregion
#region Public Methods
public void AddDanMu(DanMuMessage message)
public void AddBarrage(BarrageMessage message)
{
if (!_rateLimiter.TryAcquire())
{
@@ -81,18 +81,18 @@ namespace YwxAppWpfDanMu.Controls
{
try
{
if (DanMuFilter.ShouldFilter(message))
if (BarrageFilter.ShouldFilter(message))
return;
var args = new DanMuEventArgs(message);
DanMuAdded?.Invoke(this, args);
var args = new BarrageEventArgs(message);
BarrageAdded?.Invoke(this, args);
if (!args.Handled)
{
_danMuPool.AddDanMu(message);
_danMuPool.AddBarrage(message);
}
_performanceMonitor.RecordAddedDanMu();
_performanceMonitor.RecordAddedBarrage();
}
catch (Exception ex)
{
@@ -102,7 +102,7 @@ namespace YwxAppWpfDanMu.Controls
});
}
public void AddDanMuBatch(IEnumerable<DanMuMessage> messages)
public void AddBarrageBatch(IEnumerable<BarrageMessage> messages)
{
_queueProcessor.EnqueueBatch(() =>
{
@@ -113,18 +113,18 @@ namespace YwxAppWpfDanMu.Controls
try
{
if (DanMuFilter.ShouldFilter(message))
if (BarrageFilter.ShouldFilter(message))
continue;
var args = new DanMuEventArgs(message);
DanMuAdded?.Invoke(this, args);
var args = new BarrageEventArgs(message);
BarrageAdded?.Invoke(this, args);
if (!args.Handled)
{
_danMuPool.AddDanMu(message);
_danMuPool.AddBarrage(message);
}
_performanceMonitor.RecordAddedDanMu();
_performanceMonitor.RecordAddedBarrage();
}
catch (Exception ex)
{
@@ -172,7 +172,7 @@ namespace YwxAppWpfDanMu.Controls
double trackHeight = ActualHeight / LineCount;
for (int i = 0; i < LineCount; i++)
{
_tracks.Add(new DanMuTrack
_tracks.Add(new BarrageTrack
{
Top = i * trackHeight,
Height = trackHeight,
@@ -183,33 +183,33 @@ namespace YwxAppWpfDanMu.Controls
private static void OnLineCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DanMuControl control)
if (d is BarrageControl control)
{
control.InitializeTracks();
}
}
internal void OnDanMuItemClick(DanMuItem item)
internal void OnBarrageItemClick(BarrageItem item)
{
var args = new DanMuEventArgs(item.Message);
DanMuClick?.Invoke(this, args);
var args = new BarrageEventArgs(item.Message);
BarrageClick?.Invoke(this, args);
}
internal void OnDanMuItemRemoved(DanMuItem item)
internal void OnBarrageItemRemoved(BarrageItem item)
{
var args = new DanMuEventArgs(item.Message);
DanMuRemoved?.Invoke(this, args);
var args = new BarrageEventArgs(item.Message);
BarrageRemoved?.Invoke(this, args);
}
#endregion
internal class DanMuTrack
internal class BarrageTrack
{
public double Top { get; set; }
public double Height { get; set; }
public double Width { get; set; }
public double AvailablePosition { get; set; }
public List<DanMuItem> ActiveItems { get; } = new List<DanMuItem>();
public List<BarrageItem> ActiveItems { get; } = new List<BarrageItem>();
}
}
}

View File

@@ -1,10 +1,10 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using YwxAppWpfDanMu.Models;
using YwxAppWpfBarrage.Models;
namespace YwxAppWpfDanMu.Controls
namespace YwxAppWpfBarrage.Controls
{
public static class DanMuFilter
public static class BarrageFilter
{
private static readonly List<string> _blockedKeywords = new List<string>();
private static readonly List<Regex> _blockedPatterns = new List<Regex>();
@@ -25,7 +25,7 @@ namespace YwxAppWpfDanMu.Controls
}
}
public static bool ShouldFilter(DanMuMessage message)
public static bool ShouldFilter(BarrageMessage message)
{
if (message == null || string.IsNullOrWhiteSpace(message.Content))
return true;

View File

@@ -1,4 +1,4 @@
<UserControl x:Class="YwxAppWpfDanMu.Controls.DanMuItem"
<UserControl x:Class="YwxAppWpfBarrage.Controls.BarrageItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

View File

@@ -2,15 +2,15 @@
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using YwxAppWpfDanMu.Models;
using YwxAppWpfBarrage.Models;
namespace YwxAppWpfDanMu.Controls
namespace YwxAppWpfBarrage.Controls
{
public partial class DanMuItem : UserControl
public partial class BarrageItem : UserControl
{
public DanMuMessage Message { get; private set; }
public BarrageMessage Message { get; private set; }
public DanMuItem(DanMuMessage message)
public BarrageItem(BarrageMessage message)
{
InitializeComponent();
Message = message;
@@ -46,7 +46,7 @@ namespace YwxAppWpfDanMu.Controls
}
public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(
"Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DanMuItem));
"Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BarrageItem));
public event RoutedEventHandler Click
{

View File

@@ -2,18 +2,18 @@
using System.Windows.Controls;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using YwxAppWpfDanMu.Models;
using YwxAppWpfBarrage.Models;
namespace YwxAppWpfDanMu.Controls
namespace YwxAppWpfBarrage.Controls
{
internal class DanMuPool
internal class BarragePool
{
private readonly DanMuControl _parent;
private readonly Queue<DanMuMessage> _messageQueue = new Queue<DanMuMessage>();
private readonly BarrageControl _parent;
private readonly Queue<BarrageMessage> _messageQueue = new Queue<BarrageMessage>();
private readonly DispatcherTimer _timer;
private readonly Random _random = new Random();
public DanMuPool(DanMuControl parent)
public BarragePool(BarrageControl parent)
{
_parent = parent ?? throw new ArgumentNullException(nameof(parent));
@@ -34,7 +34,7 @@ namespace YwxAppWpfDanMu.Controls
_timer.Stop();
}
public void AddDanMu(DanMuMessage message)
public void AddBarrage(BarrageMessage message)
{
lock (_messageQueue)
{
@@ -49,7 +49,7 @@ namespace YwxAppWpfDanMu.Controls
_messageQueue.Clear();
}
_parent.DanMuCanvas.Children.Clear();
_parent.BarrageCanvas.Children.Clear();
foreach (var track in _parent._tracks)
{
track.ActiveItems.Clear();
@@ -67,20 +67,20 @@ namespace YwxAppWpfDanMu.Controls
while (_messageQueue.Count > 0)
{
var message = _messageQueue.Dequeue();
DispatchDanMu(message);
DispatchBarrage(message);
}
}
}
private void DispatchDanMu(DanMuMessage message)
private void DispatchBarrage(BarrageMessage message)
{
// 找到最适合的轨道
var track = FindBestTrack(message);
if (track == null)
return;
var danMuItem = new DanMuItem(message);
danMuItem.Click += (s, args) => _parent.OnDanMuItemClick(danMuItem);
var danMuItem = new BarrageItem(message);
danMuItem.Click += (s, args) => _parent.OnBarrageItemClick(danMuItem);
// 测量弹幕宽度
danMuItem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
@@ -90,7 +90,7 @@ namespace YwxAppWpfDanMu.Controls
Canvas.SetLeft(danMuItem, _parent.ActualWidth);
Canvas.SetTop(danMuItem, track.Top + (track.Height - danMuItem.DesiredSize.Height) / 2);
_parent.DanMuCanvas.Children.Add(danMuItem);
_parent.BarrageCanvas.Children.Add(danMuItem);
track.ActiveItems.Add(danMuItem);
// 创建动画
@@ -104,9 +104,9 @@ namespace YwxAppWpfDanMu.Controls
animation.Completed += (s, args) =>
{
_parent.DanMuCanvas.Children.Remove(danMuItem);
_parent.BarrageCanvas.Children.Remove(danMuItem);
track.ActiveItems.Remove(danMuItem);
_parent.OnDanMuItemRemoved(danMuItem);
_parent.OnBarrageItemRemoved(danMuItem);
};
// 添加透明度渐变效果
@@ -125,7 +125,7 @@ namespace YwxAppWpfDanMu.Controls
track.AvailablePosition = _parent.ActualWidth + itemWidth + 10; // 10为间距
}
private DanMuControl.DanMuTrack FindBestTrack(DanMuMessage message)
private BarrageControl.BarrageTrack FindBestTrack(BarrageMessage message)
{
if (_parent._tracks.Count == 0)
return null;

View File

@@ -1,8 +1,8 @@
using System.Windows.Media;
namespace YwxAppWpfDanMu.Controls
namespace YwxAppWpfBarrage.Controls
{
public static class DanMuSettings
public static class BarrageSettings
{
public static Color DefaultColor { get; set; } = Colors.White;
public static double DefaultFontSize { get; set; } = 14;

View File

@@ -6,14 +6,14 @@ using System.Threading.Tasks;
using System;
namespace YwxAppWpfDanMu.Models
namespace YwxAppWpfBarrage.Models
{
public class DanMuEventArgs : EventArgs
public class BarrageEventArgs : EventArgs
{
public DanMuMessage Message { get; }
public BarrageMessage Message { get; }
public bool Handled { get; set; }
public DanMuEventArgs(DanMuMessage message)
public BarrageEventArgs(BarrageMessage message)
{
Message = message;
}

View File

@@ -3,9 +3,9 @@ using System.Windows;
using System.Windows.Media;
using static System.Net.Mime.MediaTypeNames;
namespace YwxAppWpfDanMu.Models
namespace YwxAppWpfBarrage.Models
{
public class DanMuMessage
public class BarrageMessage
{
public string Content { get; set; }
public Color Color { get; set; } = Colors.Orange;

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net8.0-windows\publish\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<History>True|2025-03-29T11:47:24.3486362Z||;True|2025-03-29T17:33:52.6402455+08:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>

View File

@@ -1,13 +1,13 @@
using System;
using System.Windows.Threading;
namespace YwxAppWpfDanMu.Services
namespace YwxAppWpfBarrage.Services
{
public class DanMuDispatcher
public class BarrageDispatcher
{
private readonly Dispatcher _dispatcher;
public DanMuDispatcher(Dispatcher dispatcher)
public BarrageDispatcher(Dispatcher dispatcher)
{
_dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace YwxAppWpfBarrage.Services
{
public class BarragePerformanceMonitor
{
private readonly Stopwatch _stopwatch = new Stopwatch();
private readonly List<Exception> _errors = new List<Exception>();
private int _totalBarrageAdded;
private int _totalBarrageFiltered;
private int _totalBarrageRemoved;
public void Start()
{
_stopwatch.Start();
}
public void Stop()
{
_stopwatch.Stop();
}
public void RecordAddedBarrage()
{
_totalBarrageAdded++;
}
public void RecordFilteredBarrage()
{
_totalBarrageFiltered++;
}
public void RecordRemovedBarrage()
{
_totalBarrageRemoved++;
}
public void RecordClear()
{
_totalBarrageRemoved += _totalBarrageAdded - _totalBarrageRemoved;
}
public void RecordError(Exception ex)
{
_errors.Add(ex);
}
public PerformanceStats GetStats()
{
return new PerformanceStats
{
TotalTime = _stopwatch.Elapsed,
TotalBarrageAdded = _totalBarrageAdded,
TotalBarrageFiltered = _totalBarrageFiltered,
TotalBarrageRemoved = _totalBarrageRemoved,
Errors = _errors.ToArray(),
BarragePerSecond = _stopwatch.Elapsed.TotalSeconds > 0 ?
_totalBarrageAdded / _stopwatch.Elapsed.TotalSeconds : 0
};
}
public class PerformanceStats
{
public TimeSpan TotalTime { get; set; }
public int TotalBarrageAdded { get; set; }
public int TotalBarrageFiltered { get; set; }
public int TotalBarrageRemoved { get; set; }
public Exception[] Errors { get; set; }
public double BarragePerSecond { get; set; }
}
}
}

View File

@@ -0,0 +1,13 @@
using YwxAppWpfBarrage.Models;
namespace YwxAppWpfBarrage.Services
{
public interface IBarrageService
{
void AddBarrage(BarrageMessage message);
void AddBarrageBatch(IEnumerable<BarrageMessage> messages);
void ClearAll();
void Pause();
void Resume();
}
}

View File

@@ -1,17 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using YwxAppWpfDanMu.Services;
using YwxAppWpfBarrage.Services;
namespace YwxAppWpfDanMu.Utils
namespace YwxAppWpfBarrage.Utils
{
public class DanMuQueueProcessor
public class BarrageQueueProcessor
{
private readonly DanMuDispatcher _dispatcher;
private readonly BarrageDispatcher _dispatcher;
private readonly Queue<Action> _queue = new Queue<Action>();
private bool _isProcessing;
public DanMuQueueProcessor(DanMuDispatcher dispatcher)
public BarrageQueueProcessor(BarrageDispatcher dispatcher)
{
_dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Diagnostics;
namespace YwxAppWpfDanMu.Utils
namespace YwxAppWpfBarrage.Utils
{
public class RateLimiter
{

View File

@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>YwxAppWpfDanMu</RootNamespace>
<RootNamespace>YwxAppWpfBarrage</RootNamespace>
</PropertyGroup>
<ItemGroup>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_LastSelectedProfileId>D:\repos\YwxAppWpfDanMu\YwxAppWpfDanMu\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
</PropertyGroup>
<ItemGroup>
<Compile Update="Controls\BarrageControl.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Controls\BarrageItem.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"YwxAppWpfBarrage/1.0.0": {
"runtime": {
"YwxAppWpfBarrage.dll": {}
}
}
}
},
"libraries": {
"YwxAppWpfBarrage/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"YwxAppWpfDanMu/1.0.0": {
"runtime": {
"YwxAppWpfDanMu.dll": {}
}
}
}
},
"libraries": {
"YwxAppWpfDanMu/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"YwxAppWpfBarrage/1.0.0": {
"runtime": {
"YwxAppWpfBarrage.dll": {}
}
}
}
},
"libraries": {
"YwxAppWpfBarrage/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@@ -1,5 +1,5 @@
我在使用net8时 想用 WPF自定义控件库 实现一个弹幕库,
要求:根命名空间 YwxAppWpfDanMu
要求:根命名空间 YwxAppWpfBarrage
支持多行显示
支持不同颜色
支持头像

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]

View File

@@ -0,0 +1,89 @@
#pragma checksum "..\..\..\..\Controls\BarrageControl.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "CA3119762CFF2900153576861D181AFFE44BE11A"
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Controls.Ribbon;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Shell;
namespace YwxAppWpfBarrage.Controls {
/// <summary>
/// BarrageControl
/// </summary>
public partial class BarrageControl : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector {
#line 8 "..\..\..\..\Controls\BarrageControl.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.Canvas BarrageCanvas;
#line default
#line hidden
private bool _contentLoaded;
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "9.0.3.0")]
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Uri resourceLocater = new System.Uri("/YwxAppWpfBarrage;component/controls/barragecontrol.xaml", System.UriKind.Relative);
#line 1 "..\..\..\..\Controls\BarrageControl.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);
#line default
#line hidden
}
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "9.0.3.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 1:
this.BarrageCanvas = ((System.Windows.Controls.Canvas)(target));
return;
}
this._contentLoaded = true;
}
}
}

View File

@@ -0,0 +1,111 @@
#pragma checksum "..\..\..\..\Controls\BarrageItem.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4FB65E2B12F03963A5C83DB261F67716B4F4C6E4"
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Controls.Ribbon;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Shell;
namespace YwxAppWpfBarrage.Controls {
/// <summary>
/// BarrageItem
/// </summary>
public partial class BarrageItem : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector {
#line 9 "..\..\..\..\Controls\BarrageItem.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.Border Border;
#line default
#line hidden
#line 18 "..\..\..\..\Controls\BarrageItem.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Media.ImageBrush AvatarBrush;
#line default
#line hidden
#line 22 "..\..\..\..\Controls\BarrageItem.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.TextBlock ContentText;
#line default
#line hidden
private bool _contentLoaded;
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "9.0.3.0")]
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Uri resourceLocater = new System.Uri("/YwxAppWpfBarrage;component/controls/barrageitem.xaml", System.UriKind.Relative);
#line 1 "..\..\..\..\Controls\BarrageItem.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);
#line default
#line hidden
}
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "9.0.3.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 1:
this.Border = ((System.Windows.Controls.Border)(target));
return;
case 2:
this.AvatarBrush = ((System.Windows.Media.ImageBrush)(target));
return;
case 3:
this.ContentText = ((System.Windows.Controls.TextBlock)(target));
return;
}
this._contentLoaded = true;
}
}
}

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("YwxAppWpfBarrage")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+07479c8c6b5d1bc1a226e3f92169457cefc591c0")]
[assembly: System.Reflection.AssemblyProductAttribute("YwxAppWpfBarrage")]
[assembly: System.Reflection.AssemblyTitleAttribute("YwxAppWpfBarrage")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
// 由 MSBuild WriteCodeFragment 类生成。

View File

@@ -0,0 +1 @@
4fc22e85757014e722ecbfbe8e878646bf7cadf7b3bb390f8727d07a4118a6aa

View File

@@ -0,0 +1,16 @@
is_global = true
build_property.TargetFramework = net8.0-windows
build_property.TargetPlatformMinVersion = 7.0
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = YwxAppWpfBarrage
build_property.ProjectDir = D:\repos\YwxAppWpfDanMu\YwxAppWpfDanMu\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle = 8.0
build_property.EnableCodeStyleSeverity =

View File

@@ -1,20 +1,20 @@
WpfApp1
YwxAppWpfBarrage
1.0.0.0
winexe
library
C#
.cs
D:\repos\YwxAppWpfDanMu\WpfApp1\obj\Debug\net8.0-windows\
WpfApp1
D:\repos\YwxAppWpfDanMu\YwxAppWpfDanMu\obj\Debug\net8.0-windows\
YwxAppWpfBarrage
none
false
TRACE;DEBUG;NET;NET8_0;NETCOREAPP;WINDOWS;WINDOWS7_0;NET5_0_OR_GREATER;NET6_0_OR_GREATER;NET7_0_OR_GREATER;NET8_0_OR_GREATER;NETCOREAPP3_0_OR_GREATER;NETCOREAPP3_1_OR_GREATER;WINDOWS7_0_OR_GREATER
D:\repos\YwxAppWpfDanMu\WpfApp1\App.xaml
11407045341
6-294469655
1991235962195
MainWindow.xaml;
2-1417908758
161408862457
198-344842731
Controls\BarrageControl.xaml;Controls\BarrageItem.xaml;
False

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("YwxAppWpfDanMu")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+07479c8c6b5d1bc1a226e3f92169457cefc591c0")]
[assembly: System.Reflection.AssemblyProductAttribute("YwxAppWpfDanMu")]
[assembly: System.Reflection.AssemblyTitleAttribute("YwxAppWpfDanMu")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
// 由 MSBuild WriteCodeFragment 类生成。

View File

@@ -0,0 +1 @@
f762a7b2f0f72af0ca5331eccecc18e00fe37158686035dad7d22658ed042db7

View File

@@ -0,0 +1,16 @@
is_global = true
build_property.TargetFramework = net8.0-windows
build_property.TargetPlatformMinVersion = 7.0
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = YwxAppWpfBarrage
build_property.ProjectDir = D:\repos\YwxAppWpfDanMu\YwxAppWpfDanMu\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle = 8.0
build_property.EnableCodeStyleSeverity =

Some files were not shown because too many files have changed in this diff Show More