Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Counters – GUI for those who don't do GUI (github.com)
177 points by okaleniuk 3 months ago | hide | past | web | favorite | 44 comments

Cool idea. Here's how to do it in Linux with files:

    # create the "counters"
    touch {01..16}
    # use multitail to show all counters in a grid, 4 columns
    multitail -s 4 *
Now you can write to any of these files

    echo hello > 01
    echo world > 16
The result looks like this: https://i.imgur.com/yVWWMfr.png

You can also tell multitail to automatically rescan the directory and display new files

    # check current directory for new files once/sec. match any file
    multitail -s 4 -q 1 "*"

You can also have nice dialogs by using dialog/xdialog/zenity. For example, you can use named pipes and get a nice progress bar:

    mkfifo progress
    cat progress | zenity --progress --text='progress'  --percentage=0 &
    echo 10 > progress
    sleep 10
    echo '# Done!' > progress
    echo 100 > progress


I always use YAD, a much more feature-filled fork of zenity.


Thanks for the heads up on multitail. Here are more multitail examples [1]. Also see the manpage. I had to install multitail from software repositories. You could also just make multiple panes in tmux instead, but I prefer it when tmux is optional.

[1] http://www.vanheusden.com/multitail/examples.html

For what it’s worth you c an also do tail -f *.log (or equivalent) to tail multiple log files but it shows everything in a single stream instead of giving dedicated output locations. Any time new data comes into a file it will be prefixed by a header so you know which file received new data. But yeah, I’m also excited to know about multitaul—it was the first thing that stood out to me about GOs comment.

How have i never heard of multitail!?! TIL! Thank you!

ah wow great tip, I've done this with tmux / screen earlier and it's really neat when you want to watch multiple log files at the same time.

Regular `tail -F` also works with multiple files at the same time.

this is incredible. you have no idea how times i have been needing to monitor multiple log files on our server and never new about this. here i am opening multiple ssh terminals and switching between them. you are a life saver.

This is great. Is there a way to remove those borders?

The composability of Unix tools still amazes me! Great job.

> The buttons seem misaligned but there is logic in it. The buttons that has to do with the coutners are closer to the counters. And the buttons that expose the window handler are closer to the window handler. And yes, the number on top is the window handler.

I'm having a bit of trouble understanding this, since I can't see how this works. How does [C], which "copies a C-style SendMessage template to the clipboard", have anything to do with exposing the window handler?

If you look at the SendMessage code examples, they contain the window handle as the first parameter. Looks like that's a convenience feature to reduce the amount of typing required to get data into the target. It basically generates code to communicate with the instance you pressed the button on I believe.

My guess is that the copied code includes the handle value of the running instance as an integer literal.

See the examples on the page.

I've heard from game dev circles that some use Dear ImGui in the same spirit - as quick ad-hoc sort of GUI. A printf on steroids, if you will.

That + this post gives me an interesting idea... a local network interface for ImGui for environments where you don't have a native window, or there are no convenient bindings for ImGui.

From the name and context I was expecting something directly releated to ImGui, but imdebug is not directly related to ImGui nor to immediate mode GUIs in general in any way. Still interesting however, even though it wasn't what I was expecting.

It was the network interface aspect that made me think of it.

Pretty much this. Basically its an easy way to merge in instrumentation and a console when you need one.

I wouldn't personally use this since my preference usually goes towards terminal UIs but I love seeing these personal productivity tools that people come up with. Nice work (and kudos on actually maintaining readable assembly code)!

Isn't it annoying to have to change out window handles manually all the time? Or did that just become muscle memory after using the concept for that long?

I try not to keep the SendMessages for too long. We actually have a Linux gate-build at work so they only live on local machines.

But every once in a while I spawn them all across the code to hunt some bug, and then I think I got it, and I do the victorious "Aha!" and close the window. And, of course, it's not it and then yes it gets annoying to update the handlers.

A thought sprung to mind: In *n?x environments, if I were implementing something like this I think I'd do it using an env var for sync. Think something like:

  $ eval $(start_counters); # start process, print 'COUNTERS_ID=...'
  $ ./myapp
i.e. "stealing the way ssh-agent works for fun and profit"

I'm suspecting you already thought of this sort of trick and rejected it as not worth the extra complication for the rare annoyance, but since it didn't pop into my head until hours after originally reading this comment I figure it was worth noting just in case.

The ""deluxe"" (ie far more complicated) version of this might be to use ETW, which is one of those extremely Microsoft APIs that's both powerful but obtuse and can only really be learned from the one blogger providing examples. Which in this case is the amazing series of posts from https://randomascii.wordpress.com/2015/09/24/etw-central/

ETW would also work in those rare situations where SendMessage() doesn't, such as from a device driver, and can more easily be logged.

From the title I thought it would be some type of data dashboard with a simple conf file to grab all the data. The conf file could have options like "endpoint" for the API endpoint, "type" for the chart type (bar, plot, pie, etc), "target" for how to target the data in the response (res["someData"]), or "targetx" and "targety" for graphs, "labels" and "axis" for assigning labels to the data, and "style" for selecting different variations for the graphs/chart such as solid/dotted/dashed for line types.

This reminds me of those old carpenter tools and worn workbenches. Deceptively simple and specific but its really a complex multitool full of subtleties embedded mostly in how you use it rather than in another GUI or command line option.

In assembly language and targeting windows as well. Novelty++.

Ehm, this just how windows work, you are having a hwnd (window handle) and message with optional parameters. There are hundreds of messages and WM_USER just defines start of custom defined messages. Typically you define your custome message as WM_USER + arbitrary number. And you also have PostMessage.

You're right, it is generally a good idea to use messages for this. It is also better performance wise to keep all the dispatching in one place.

But I tried that at the very beginning and it was rather inconvenient since I had to drag defines to every place I want to send a message from. "WM_USER + 'R'" might have worked but it's worse than "WM_USER, 'R'" aesthetically. And there is an extra parameter anyway.

PostMessage is also better for writing things to the counters since it's asynchronous. But it doesn't work for reading. It's just more convenient to have one function do both but of course you can post messages too.

It's a silly tool anyway. Basically made of compromises.

Given that this is <500 lines of assembly this is frankly amazing given the overall complexity of the layout. Very clever.

gnuplot, graphviz, ministat can help you visualize stuff fast.

For interactive stuff, you can create a HTTP server and send requests to it from a web UI. For example, using this: https://github.com/yhirose/cpp-httplib

gnuplot and graphviz both are a staple but I've never heard of ministat so far - looks really useful though.

This is neat. From time to time I use a thing I call livedisplay. It is a http endpoint that you can send json message to an it will forward it to web interface via websocket. Obviously much more overhead than 16 Counters, but works on network and cross platform.

I can't relate to this environment or workflow but off the top of my head if I wanted to do something like this I'd use some kind of pub-sub and publish to it from one place and read from another - is that what this is ? Or am I missing something?

Yes, except there isn't really a subscribe step so it's really just "pub". You are manually publishing messages to a static window handle.

Got it

Is it not possible to just use redis or some windows equivalent for this kind of requirement?

Oleksandr, I can't help but be reminded of http://okcancel.com/strips/okcancel20031010.gif :)

To be fair, your software probably was not intended to be used by anyone else and publishing it to Github is just for sharing the underlying idea.

MFC, still alive? In this “web” world, who still code use MFC framework?

Yours truly and many, many others. I do not actually use MFC as I only use C++ for servers. GUI things in my case go to Delphi/Lazarus. There is a whole world outside of that web juggernaut.

Delphi! Whaaaaat a surprise !

I still miss MFC/windows programming a lot, I think in many ways it's quite efficient.

But for job seeking it's not a good idea, opening for windows gui is quite rare.

Maybe I should setup a web(!!) For lonely job seeker on windows programming / and Delphi/lisp/scheme / all other good oldies forgotten by rest of the world.

Delphi is quite popular still in Europe. Also it is not just Windows. Delphi/Lazarus produce exe for all the major platforms. I was doing some GUI app for Raspberry Pi and I had Lazarus IDE running right there, along with debugging and all other goodies. Also I mostly develop products and are on my own since 2000. Not much concern on my side about what all those big cloudy companies think. Eff them ;)

Where do you see MFC? This straight up uses Win32.

Win32 in assembly. Serious commitment to minimalism right there.

What's MFC to do with this?

MFC programs look like Win32 programs. You often can't tell the difference from a screenshot.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact