wsui 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/lib/wsui.rb +127 -0
  4. data/wsui.gemspec +18 -0
  5. metadata +88 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 79eb85fc954388860540b734d23489c02149475852ec0d31cf037d01cc4dbd8f
4
+ data.tar.gz: 6fea7d780005fa299d347d4e2de16be5ffbb3af492fbf3512e605b745130256b
5
+ SHA512:
6
+ metadata.gz: 20a7d5299d5769657b5685ac266e9416332c94da297a90185ee62f0abceb440c160dfa7c357ccd50b5a8c066a32fbed3de3968fb8df166199394c4518b59bffd
7
+ data.tar.gz: 8a1267192d8686b7d986afdf9587f04beb527cdb6043a4e72c3b02bfd6e4cbe4327e7d4ff0b8aeb021278df018911a4ec0e2041d5b5bf42c975595e4983ddc1e
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Victor Maslov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/lib/wsui.rb ADDED
@@ -0,0 +1,127 @@
1
+ module WSUI
2
+ require "set"
3
+ require "async/websocket/adapters/rack"
4
+ require "async/http/endpoint"
5
+ require "falcon"
6
+ S = Struct.new :value, :click
7
+ def self.start port = 7001, html = "", fps: 5, &block
8
+ app = Module.new do
9
+ @connections = Set.new
10
+ @port = port
11
+ @fps = fps
12
+ @block = block
13
+ def self.call env
14
+ f = lambda do |o|
15
+ if o.is_a? S
16
+ {wsui_id: o.__id__, value: o.value}
17
+ elsif o.respond_to? :each
18
+ o.map &f
19
+ else
20
+ o
21
+ end
22
+ end
23
+ Async::WebSocket::Adapters::Rack.open env, protocols: %w{ ws } do |connection|
24
+ @connections << connection
25
+ while message = connection.read
26
+ if message.key? :id
27
+ t = begin
28
+ ObjectSpace._id2ref message[:id]
29
+ rescue RangeError
30
+ # maybe when we click too fast and the page has 'old' refs
31
+ end
32
+ p t
33
+ t.click&.call t if t.respond_to? :click
34
+ end
35
+ t = f.call(@block.call(message)).to_json
36
+ @connections.each do |connection|
37
+ connection.write t
38
+ connection.flush
39
+ end
40
+ end
41
+ rescue Protocol::WebSocket::ClosedError
42
+ p :closed
43
+ ensure
44
+ @connections.delete connection
45
+ end or [200, [], [<<~HEREDOC]]
46
+ <html>
47
+ <head>
48
+ <meta charset="UTF-8">
49
+ <script src="https://github.com/processing/p5.js/releases/download/v1.4.2/p5.min.js"></script>
50
+ <script src="https://cdn.jsdelivr.net/gh/abachman/p5.websocket/dist/p5.websocket.min.js"></script>
51
+ <script>
52
+ var all = null;
53
+ var regions = [];
54
+ var need = false; // force draw() on click
55
+ function setup() {
56
+ frameRate(#{@fps});
57
+ createCanvas(windowWidth, windowHeight);
58
+ textAlign(CENTER, CENTER);
59
+ connectWebsocket("ws://" + window.location.host);
60
+ };
61
+ function messageReceived(data) {
62
+ // console.log(data);
63
+ all = JSON.parse(data);
64
+ if (need) {
65
+ need = false;
66
+ draw();
67
+ }
68
+ };
69
+ function draw() {
70
+ // console.log(all);
71
+ clear();
72
+ regions = [];
73
+ let fv = function(o, left, top, width, height) {
74
+ if (o && o.wsui_id) {
75
+ regions.push({id: o.wsui_id, left: left, top: top, width: width, height: height});
76
+ o = o.value;
77
+ };
78
+ if (o === null) return;
79
+ if (Number.isFinite(o) || typeof o === "string" || o instanceof String) {
80
+ textSize(min(100, textSize() * min(height / textWidth("W"), width / textWidth(o))));
81
+ text(o, left + width / 2, top + height / 2)
82
+ } else o.forEach( function(e, i) {
83
+ fh(e, left, top + height / o.length * i, width, height / o.length);
84
+ } );
85
+ };
86
+ let fh = function(o, left, top, width, height) {
87
+ if (o && o.wsui_id) {
88
+ regions.push({id: o.wsui_id, left: left, top: top, width: width, height: height});
89
+ o = o.value;
90
+ };
91
+ if (o === null) return;
92
+ if (Number.isFinite(o) || typeof o === "string" || o instanceof String) {
93
+ textSize(min(100, textSize() * min(height / textWidth("W"), width / textWidth(o))));
94
+ text(o, left + width / 2, top + height / 2)
95
+ } else o.forEach( function(e, i) {
96
+ fv(e, left + width / o.length * i, top, width / o.length, height);
97
+ } );
98
+ };
99
+ fv(all, 0, 0, windowWidth, windowHeight);
100
+ sendMessage({});
101
+ };
102
+ function mouseClicked() {
103
+ regions.some( function(e) {
104
+ if (mouseX >= e.left && mouseX <= e.left + e.width && mouseY >= e.top && mouseY <= e.top + e.height) {
105
+ sendMessage({id: e.id});
106
+ need = true;
107
+ return true;
108
+ };
109
+ } );
110
+ };
111
+ </script>
112
+ </head>
113
+ <body style="margin:0"><main></main></body>
114
+ </html>
115
+ HEREDOC
116
+ end
117
+ end
118
+ Thread.new do
119
+ Async do
120
+ Falcon::Server.new(
121
+ Falcon::Server.middleware(app),
122
+ Async::HTTP::Endpoint.parse("http://0.0.0.0:#{port}")
123
+ ).run
124
+ end
125
+ end
126
+ end
127
+ end
data/wsui.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "wsui"
3
+ spec.version = "0.0.0"
4
+ spec.summary = "websockets-based HTML GUI for Ruby runtime objects"
5
+ spec.metadata = {"source_code_uri" => "https://github.com/nakilon/wsui"}
6
+
7
+ spec.author = "Victor Maslov aka Nakilon"
8
+ spec.email = "nakilon@gmail.com"
9
+ spec.license = "MIT"
10
+
11
+ spec.required_ruby_version = ">=2.5" # just for do-ensure-end
12
+
13
+ spec.add_dependency "protocol-websocket", "<0.11.0" # https://github.com/socketry/protocol-websocket/issues/13
14
+ spec.add_dependency "async-websocket"
15
+ spec.add_dependency "falcon", ">0.12.0" # the "require event/terminal" exception
16
+
17
+ spec.files = %w{ LICENSE wsui.gemspec lib/wsui.rb }
18
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wsui
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Victor Maslov aka Nakilon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-07-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: protocol-websocket
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "<"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.11.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "<"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.11.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: async-websocket
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: falcon
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.12.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.12.0
55
+ description:
56
+ email: nakilon@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - LICENSE
62
+ - lib/wsui.rb
63
+ - wsui.gemspec
64
+ homepage:
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ source_code_uri: https://github.com/nakilon/wsui
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '2.5'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubygems_version: 3.2.3
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: websockets-based HTML GUI for Ruby runtime objects
88
+ test_files: []