• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

luttje / Key2Joy / 6517266969

14 Oct 2023 11:05AM UTC coverage: 12.469% (+0.2%) from 12.308%
6517266969

push

github

web-flow
Implementing plugins for better separation (#39)

* Start implementing plugins for better separation
* massive refactor in attempt to split appdomains for plugins
* (breaks old mapping profiles)
* Fix error when switching from mouse button trigger to keyboard trigger and clicking in the combobox where the mouse button capture textbox is.
* Simplify code by removing legacy
* SImplify grouping actions
* Fix profile and add helpful opposite mapping generator tool
* Change solution hierarchy
* Restrict AppDomain plugins went from Zone.MyComputer -> .Internet
* create keypair in ci
* Install the .NET framework tools
* Run command in workflow
* Plugin permissions. Plugins disabled by default
* update readme (icon is no longer used)
* Plugin action runs in seperated process
* Remove unused dependencies.
* Fix action name display for mapping
* Fix Lua plugin script calls (NOTE: laggy when using MessageBox)
* convert project to sdk style
* Add editorconfig and start cleaning up
* Fix documentation. Update namespaces to match files (breaks profiles)
* Include all projects in tests, disable building docs on debug
* Add messagebox script action
* Add tests for pluginhost
* Remove administrator from window title test
* add some icons to ui
* Add enabling/disabling plugins
* Close plugins when Key2Joy shuts down
* Fix appcommand failing
* Fix plugin permission form crashing. Fix plugin load exception not showing warning
* Handle plugin host closing better when app has crashed
* Seperate host and client logic in remote event subscriber
* Ensure the PluginHost shuts down if the app crashes
* Better error output for plugins
* Fix cmd interop not working, add some tests
* also generate docs on plugins
* Fix build order with docs
* Fix enum script parameters and ensure actions share environment scopes
* Fix _wpftmp folders being created dotnet/wpf#2930
* Fix sequence action. Add disabled trigger/action for unloaded plugins on start... (continued)

180 of 1703 branches covered (0.0%)

Branch coverage included in aggregate %.

6419 of 6419 new or added lines in 207 files covered. (100.0%)

1035 of 8041 relevant lines covered (12.87%)

8445.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.95
/Core/Key2Joy.Contracts/Plugins/Remoting/RemoteEventSubscriberClient.cs
1
using System;
2
using System.Diagnostics;
3
using System.IO;
4
using System.IO.Pipes;
5
using System.Threading;
6
using System.Threading.Tasks;
7

8
namespace Key2Joy.Contracts.Plugins.Remoting;
9

10
public class RemoteEventSubscriberClient
11
{
12
    public event EventHandler Disposing;
13

14
    private readonly NamedPipeClientStream pipeStream;
15

16
    private DateTime lastHeartbeatAt = DateTime.Now;
9✔
17
    private CancellationTokenSource pipeCancellation;
18

19
    internal RemoteEventSubscriberClient(string portName)
9✔
20
    {
9✔
21
        this.pipeStream = new NamedPipeClientStream(
9✔
22
            ".",
9✔
23
            RemotePipe.GetClientPipeName(portName),
9✔
24
            PipeDirection.InOut,
9✔
25
            PipeOptions.Asynchronous);
9✔
26
        this.pipeStream.Connect();
9✔
27
        this.pipeStream.ReadMode = PipeTransmissionMode.Message;
9✔
28

29
        this.pipeCancellation = new CancellationTokenSource();
9✔
30

31
        this.InitBackgroundHeartbeatThread();
9✔
32
    }
9✔
33

34
    /// <summary>
35
    /// Called from the client to send a message to the host.
36
    /// </summary>
37
    /// <param name="message"></param>
38
    /// <exception cref="IOException"></exception>
39
    internal void SendToHost(string message) => RemotePipe.WriteMessage(this.pipeStream, message);
9✔
40

41
    public void AskHostToInvokeSubscription(RemoteEventArgs e) => this.SendToHost(e.Subscription.Id.ToString());
×
42

43
    /// <summary>
44
    /// Checks in the background if the host has shown any sign of life recently.
45
    /// </summary>
46
    private void InitBackgroundHeartbeatThread()
47
    {
9✔
48
        // Registers heartbeats from the host.
49
        var pipeListenerBackgroundThread = Task.Run(() =>
9✔
50
        {
9✔
51
            try
9✔
52
            {
9✔
53
                while (!this.pipeCancellation.IsCancellationRequested)
2,467,730✔
54
                {
2,467,730✔
55
                    var message = RemotePipe.ReadMessage(this.pipeStream);
2,467,730✔
56

9✔
57
                    if (string.IsNullOrEmpty(message))
2,467,721✔
58
                    {
2,467,721✔
59
                        continue;
2,467,721✔
60
                    }
9✔
61

9✔
62
                    Console.WriteLine($"Remote Message: {message}");
×
63
                    this.lastHeartbeatAt = DateTime.Now;
×
64
                }
×
65
            }
×
66
            catch (ObjectDisposedException) { } // in case pipe closed
×
67
        });
9✔
68

69
        // Checks if the last heartbeat was too long ago.
70
        var pipeCancellerBackgroundThread = Task.Run(() =>
9✔
71
        {
9✔
72
            while (!this.pipeCancellation.IsCancellationRequested)
25✔
73
            {
25✔
74
                if (DateTime.Now - this.lastHeartbeatAt > RemoteEventSubscriber.MaxHeartbeatInterval)
25✔
75
                {
×
76
                    Console.WriteLine("Host is not responding. Shutting down.");
×
77
                    this.Dispose();
×
78
                    return;
×
79
                }
9✔
80

9✔
81
                Thread.Sleep(1000);
25✔
82
            }
16✔
83
        });
9✔
84
    }
9✔
85

86
    public void Exit()
87
    {
×
88
        if (!this.pipeStream.IsConnected)
×
89
        {
×
90
            return;
×
91
        }
92

93
        try
94
        {
×
95
            this.SendToHost(RemoteEventSubscriber.SignalExit);
×
96
        }
×
97
        catch (IOException ex)
×
98
        {
×
99
            Output.WriteLine(ex);
×
100
            Debug.WriteLine(ex);
×
101
        }
×
102

103
        this.Dispose();
×
104
    }
×
105

106
    public void Dispose()
107
    {
×
108
        this.Disposing?.Invoke(this, EventArgs.Empty);
×
109

110
        this.pipeStream?.Dispose();
×
111

112
        this.pipeCancellation?.Cancel();
×
113
    }
×
114
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc