Page 21 of 98

Re: Life tag testing

Posted: September 1st, 2016, 7:25 pm
by dvgrn
rowett wrote:OK so that one is my fault. Fixed in the next build. That's 1 each.
Let's not try to keep score. Here's another thing that came up today that I almost reported as a bug, but it's a feature:

Code: Select all

x = 1104, y = 1090, rule = B3/S23
28b2o$28b2o3$33b2o$33b2o11$52bo$51bobo$52b2o3$b2o$obo$bo13$72bo$71bobo
$72b2o9$37b2o$36bo2bo$36bo2bo$37b2o$30bo$29bobo$29bobo$30bo2$92bo$91bo
bo$92b2o9$57b2o$56bo2bo$56bo2bo$57b2o$50bo$49bobo$49bobo$50bo13$77b2o$
76bo2bo$76bo2bo$77b2o$70bo$69bobo$69bobo$70bo5$105b2o$105b2o3$110b2o$
110b2o3$91bo46bo$90bobo44bobo$90b2o46b2o3$88b2o$88bobo$89bobo$90bo12$
111bo$110bobo$110b2o3$108b2o$108bobo$109bobo$110bo$171b2o$171b2o3$176b
2o$176b2o2$141b2o$141b2o3$131bo14b2o$130bobo13b2o$130b2o3$128b2o$128bo
bo$129bobo$130bo12$157b2o$156bo2bo$156bo2bo$157b2o$150bo25b2o$149bobo
24b2o$149bobo$150bo$181b2o$181b2o9$220bo$219bobo$177b2o41b2o$176bo2bo$
176bo2bo$177b2o$170bo$169bobo$169bobo$170bo12$222bo$191bo29bobo$190bob
o29b2o$190b2o3$188b2o$188bobo$189bobo$190bo3$250bo$249bobo$250b2o7$
217b2o$216bo2bo$216bo2bo$217b2o$210bo$209bobo$209bobo$210bo12$262bo$
237b2o22bobo$236bo2bo22b2o$236bo2bo$237b2o$230bo$229bobo$229bobo$230bo
$309b2o$309b2o3$314b2o$314b2o7$257b2o$256bo2bo$256bo2bo$257b2o$250bo$
249bobo$249bobo$250bo13$271bo$270bobo$270b2o44bo$315bobo$316b2o$268b2o
$268bobo$269bobo$270bo5$344b2o$344b2o3$349b2o$349b2o2$291bo$290bobo$
290b2o3$288b2o$288bobo$289bobo$290bo12$311bo$310bobo44bo22bo$310b2o44b
obo20bobo$357b2o21b2o2$308b2o$308bobo$309bobo$310bo12$331bo$330bobo$
330b2o3$328b2o$328bobo$329bobo$330bo12$357b2o$356bo2bo$356bo2bo$357b2o
$350bo$349bobo$349bobo$350bo3$387b2o$387b2o3$392b2o$392b2o3$420bo$419b
obo$371bo48b2o$370bobo$370b2o3$368b2o$368bobo$369bobo$370bo12$391bo$
390bobo$390b2o3$388b2o$388bobo$389bobo$390bo4$448b2o$448b2o3$421b2o30b
2o$421b2o30b2o3$411bo14b2o$410bobo13b2o$410b2o3$408b2o$408bobo$409bobo
$410bo12$437b2o$436bo2bo$436bo2bo$437b2o$430bo$429bobo$429bobo$430bo6$
464b2o$464b2o3$469b2o29b2o$469b2o29b2o2$451bo$450bobo52b2o$450b2o53b2o
3$448b2o$448bobo$449bobo$450bo10$502b2o$502b2o$471bo$470bobo$470b2o35b
2o$507b2o2$468b2o$468bobo$469bobo$470bo79bo$549bobo$550b2o10$497b2o$
496bo2bo$496bo2bo$497b2o$490bo$489bobo$489bobo$490bo13$511bo$510bobo$
510b2o3$508b2o$508bobo$509bobo39bo$510bo39bobo$551b2o9$579b2o$579b2o$
531bo$530bobo$530b2o52b2o$584b2o2$528b2o$528bobo$529bobo$530bo6$587bo$
586bobo$587b2o4$551bo$550bobo$550b2o3$548b2o$548bobo$549bobo$550bo2$
627b2o$627b2o3$632b2o$632b2o5$577b2o$576bo2bo$576bo2bo$577b2o$570bo$
569bobo$569bobo$570bo13$591bo$590bobo$590b2o$635bo$634bobo$588b2o45b2o
$588bobo$589bobo$590bo61b2o$652b2o3$657b2o$657b2o7$611bo$610bobo$610b
2o3$608b2o$608bobo$609bobo$610bo12$637b2o$636bo2bo$636bo2bo$637b2o$
630bo$629bobo$629bobo$630bo$692b2o$692b2o$667b2o$667b2o$697b2o$697b2o$
672b2o$672b2o5$651bo$650bobo$650b2o3$648b2o$648bobo$649bobo$650bo12$
677b2o$676bo2bo$676bo2bo$677b2o18b2o$670bo26b2o$669bobo$669bobo$670bo
31b2o$702b2o5$745bo$744bobo$745b2o5$697b2o$696bo2bo$696bo2bo$697b2o$
690bo$689bobo$689bobo$690bo13$711bo$710bobo$710b2o3$708b2o$708bobo$
709bobo38b2o21b2o$710bo39b2o21b2o3$755b2o21b2o$755b2o21b2o8$731bo$730b
obo$730b2o3$728b2o$728bobo$729bobo$730bo12$757b2o$756bo2bo$756bo2bo$
757b2o$750bo$749bobo$749bobo$750bo$812b2o$812b2o3$817b2o$817b2o4$781bo
$780bobo$781b2o$771bo$770bobo$770b2o3$768b2o$768bobo$769bobo$770bo12$
797b2o$796bo2bo$796bo2bo$797b2o$790bo$789bobo$789bobo62b2o$790bo63b2o
2$829bo$828bobo28b2o$829b2o28b2o9$811bo$810bobo$810b2o3$808b2o$808bobo
$809bobo$810bo12$837b2o$836bo2bo$836bo2bo$837b2o$830bo$829bobo$829bobo
$830bo6$904b2o$904b2o$863bo$862bobo$863b2o44b2o$909b2o2$851bo$850bobo$
850b2o3$848b2o$848bobo$849bobo$850bo12$871bo$870bobo$870b2o3$868b2o66b
o$868bobo64bobo$869bobo64b2o$870bo3$907bo$906bobo$907b2o7$891bo$890bob
o$890b2o3$888b2o$888bobo$889bobo$890bo12$917b2o$916bo2bo20bo$916bo2bo
19bobo$917b2o21b2o$910bo$909bobo$909bobo$910bo10$980b2o$980b2o2$937b2o
$936bo2bo45b2o$936bo2bo45b2o$937b2o$930bo$929bobo$929bobo$930bo13$951b
o$950bobo$950b2o3$948b2o$948bobo23b2o$949bobo22b2o$950bo2$979b2o29b2o$
979b2o29b2o3$1015b2o$1015b2o5$977b2o$976bo2bo$976bo2bo$977b2o$970bo$
969bobo$969bobo$970bo13$997b2o$996bo2bo19b2o$996bo2bo19b2o$997b2o$990b
o65b2o$989bobo32b2o30b2o$989bobo32b2o$990bo$1061b2o$1061b2o11$1017b2o$
1016bo2bo$1016bo2bo$1017b2o$1010bo$1009bobo$1009bobo$1010bo2$1071b2o$
1071b2o3$1076b2o$1076b2o6$1037b2o$1036bo2bo$1036bo2bo$1037b2o$1030bo$
1029bobo$1029bobo$1030bo13$1057b2o$1056bo2bo$1056bo2bo$1057b2o$1050bo$
1049bobo$1049bobo50b2o$1050bo51b2o13$1067b3o$1067bo$1068bo!
#C [[  AUTOFIT AUTOSTART X 555 Y 512  Z 2 STEP 20 STOP 9660 ]]
I wanted to get the neat zoom-in effect toward the end, but even without HISTORYFIT I couldn't get it to work... because I had pasted in the pattern as a LifeHistory pattern instead of plain old two-state RLE.
rowett wrote:The release will be a while since:
  1. ...
  2. I'm currently improving Golly's rendering performance for zoomed in patterns (zoom x2 was particularly bad for patterns with lots of cells).
    ...
Awesome! That's an improvement that has been needed for a long time. I'll try not to distract you too much, then.

Seems to me that Golly also used to be strangely slow at drawing the background grid at some zoom levels, such that if you just turned off the grid it would speed up rendering significantly. I don't seem to be seeing that so much in Golly 2.8, though.

Re: Life tag testing

Posted: September 1st, 2016, 9:47 pm
by rowett
dvgrn wrote:I wanted to get the neat zoom-in effect toward the end, but even without HISTORYFIT I couldn't get it to work... because I had pasted in the pattern as a LifeHistory pattern instead of plain old two-state RLE.
Yes that's a good point. LifeViewer handles LifeHistory patterns differently than plain two-state RLE since it uses the multi-state bounding box as the minimum bounding box (otherwise the default zoom could ignore overlay states with important information). Perhaps this should be a configurable option?
dvgrn wrote:Seems to me that Golly also used to be strangely slow at drawing the background grid at some zoom levels, such that if you just turned off the grid it would speed up rendering significantly. I don't seem to be seeing that so much in Golly 2.8, though.
I haven't looked at this yet but will be running some performance benchmarks soon on various rendering configurations (grid on/off, layers etc.) to see if there are other areas I should investigate, and also to be able to measure improvements to zoom > 1 rendering.

Re: Life tag testing

Posted: September 2nd, 2016, 9:40 am
by rowett
The original Golly renderer at zooms of 2x, 4x, 8x, 16x and 32x has performance proportional to the number of live cells in the viewport (i.e. visible on the screen). So for patterns with a few cells it performs very well, and at large zooms it performs reasonably well, since there aren't many cells that fit on the screen at large zooms.

The new renderer I've built and am testing has performance that's proportional to the size of the tiles drawn in screen pixels (regardless of the number live cells). It's not as quick as the original for patterns with very few cells, but it's significantly faster when there are many live cells. So in effect it creates a much better performance floor (or worst case) but doesn't have as good a best case.

Some preliminary results on my laptop with the Generations->Fireworks pattern (used because it's a worse case for the original renderer since it creates a large number of cells which remain relatively static in number):

Code: Select all

Zoom  Original  New     Faster
x1    1ms       (same)  1.0x
x2    80ms      3ms     26.7x
x4    70ms      6ms     11.7x
x8    50ms      10ms    5.0x
x16   14ms      10ms    1.4x
x32   4ms       10ms    0.4x
You can see at x32 zoom the original renderer is 2.5x as quick as the new one, because there are relatively few live cells that fit on the screen at x32 zoom. In all other cases the new renderer is faster, but again this is a worst case pattern due to the large number of live cells.
It may be worth having the renderer dynamically choose original vs new mode based on cell population, depending on the new mode performance floor following further testing.

Re: Life tag testing

Posted: September 3rd, 2016, 5:26 pm
by rowett
I've committed my changes to Golly for improved rendering speeds at 2x, 4x and 8x zoom. Now back to LifeViewer for a bit...

Re: Life tag testing

Posted: September 9th, 2016, 12:37 pm
by rowett
rowett wrote:I've committed my changes to Golly for improved rendering speeds at 2x, 4x and 8x zoom. Now back to LifeViewer for a bit...
OK so I got sidetracked by more recently committed Golly improvements:
  • 8x zoom rendering speed improvements when icons displayed
  • grid lines drawing speed improvements
Next on the LifeViewer backlog:
  • complete the new heap allocation model
  • asm.js prototype for ConvertToPens function
  • bug fix for TRACK timing (implemented, pending release)
  • bug fix for "Life ended at" when STEP > 1
  • B0 support for non-totalistic rules (port from Golly)
I'm also thinking about a new renderer for Golly (based on the LifeViewer approach) but it's going to require a fair amount of work since the two approaches taken are very different: LifeViewer starts with screen pixels and works backwards to find an appropriate cell, Golly starts with cell tiles and projects them forwards onto the display.

Re: Life tag testing

Posted: September 9th, 2016, 2:05 pm
by dvgrn
rowett wrote:
rowett wrote:I've committed my changes to Golly for improved rendering speeds at 2x, 4x and 8x zoom. Now back to LifeViewer for a bit...
OK so I got sidetracked by more recently committed Golly improvements...
I'm also thinking about a new renderer for Golly (based on the LifeViewer approach) but it's going to require a fair amount of work since the two approaches taken are very different: LifeViewer starts with screen pixels and works backwards to find an appropriate cell, Golly starts with cell tiles and projects them forwards onto the display.
You've already probably contributed more code to Golly than I have, by the way. At this rate you should pretty soon get formally mentioned as one of the Golly Gang, if you want to be on the list -- e.g., on the Golly SourceForge main page.

It's great to hear that you're patching up the long-neglected rendering code. Golly has always relied on its HashLife and QuickLife speed tricks as an excuse to be inexcusably inefficient in other areas...!

It would be even more greater if it was possible to allow Golly to join the modern age in terms of allowing fractional zoom levels. It's actually pretty awkward to inspect and figure out complex patterns, when there are no visual cues about where subpatterns move to on the screen, as you're jumping from 1:4 to 1:2 to 1:1, and especially into the arbitrary color change at 2:1.

-- Huh. Speaking of rendering problems, I'm seeing a hiccup now, related to the pop-up toolbar in Golly 2.8. The arrow buttons work fine, but for the + and - buttons, the view only updates in the small area behind the popup toolbar, until the cursor moves away from the toolbar again. Then the whole view magically refreshes. Do you see the same effect, or is that specific to my OS? (Windows 10)

Re: Life tag testing

Posted: September 10th, 2016, 12:30 am
by rowett
dvgrn wrote:Speaking of rendering problems, I'm seeing a hiccup now, related to the pop-up toolbar in Golly 2.8. The arrow buttons work fine, but for the + and - buttons, the view only updates in the small area behind the popup toolbar, until the cursor moves away from the toolbar again. Then the whole view magically refreshes. Do you see the same effect, or is that specific to my OS? (Windows 10)
I don't see that on Windows 10 64bit (vanilla Golly 2.8.) or on my dev build on Ubuntu 14.04 64bit (Golly 2.9b1).

Re: Life tag testing

Posted: September 13th, 2016, 8:08 pm
by rowett
dvgrn wrote:It would be even more greater if it was possible to allow Golly to join the modern age in terms of allowing fractional zoom levels. It's actually pretty awkward to inspect and figure out complex patterns, when there are no visual cues about where subpatterns move to on the screen, as you're jumping from 1:4 to 1:2 to 1:1, and especially into the arbitrary color change at 2:1.
On initial inspection it's a big job. Golly is optimized for generation speed which makes the rendering (among other things like bounded grids) complex.
LifeViewer was optimized for rendering speed first and from there I went on to figure out how to improve generation speed.
Within the current Golly model I've optimized the OpenGL rendering backend. I'm in the middle of optimizing each individual algorithm drawing routine (mostly by moving from individual R, G, B, A components to single RGBA values). I don't fancy rewriting all of the algorithm drawing routines for smooth scaling.
What I may do instead is ask some kind soul called Andrew to meet me half way and render from the algorithms to a flat 1x1 grid regardless of zoom from where I'll do the scaling and other magic between the algorithm draw and the OpenGL backend.

Re: Life tag testing

Posted: September 13th, 2016, 11:38 pm
by Andrew
dvgrn wrote:At this rate you should pretty soon get formally mentioned as one of the Golly Gang
Chris is already in the Gang, thanks to his work on non-totalistic rule support. His name appears in the About Golly dialog box and elsewhere.
if you want to be on the list -- e.g., on the Golly SourceForge main page.
The names listed there are only the people with admin permissions. Chris, I'm happy to give you those if you want them. Then you can make changes to the web pages, fix any typos or whatever.
It's great to hear that you're patching up the long-neglected rendering code.
"long-neglected"?! Over the last year or so I've spent *weeks* replacing the old wxWidgets drawing code with OpenGL code. I was happy just to get it all working and let others get the glory of making it fast. :wink: (Thanks Chris!)

Re: Life tag testing

Posted: September 14th, 2016, 8:00 am
by Andrew
rowett wrote:What I may do instead is ask some kind soul called Andrew to meet me half way and render from the algorithms to a flat 1x1 grid regardless of zoom from where I'll do the scaling and other magic between the algorithm draw and the OpenGL backend.
I think it's Tom who you'll need to ask. He designed and wrote pretty much all of the abstract drawing code and viewport class that assumes scaling is done by powers of 2. I just tweaked things a bit when we decided to add support for icons.

Are you just talking about zooming in, or zooming out as well? The latter would require a major rethink given that Golly can zoom out to ridiculously large scales. Zooming in to arbitrary scales would be a lot easier. The actual rendering part would be quite simple -- the messy part will be modifying all the GUI code that handles mouse clicks, selections, etc. And what do we do about scripts that call g.getmag()?

Re: Life tag testing

Posted: September 14th, 2016, 9:53 am
by dvgrn
Andrew wrote:
dvgrn wrote:
It's great to hear that you're patching up the long-neglected rendering code.
"long-neglected"?! Over the last year or so I've spent *weeks* replacing the old wxWidgets drawing code with OpenGL code. I was happy just to get it all working and let others get the glory of making it fast. :wink: (Thanks Chris!)
Dear me, yes, that was terribly impolitic of me, wasn't it? My apologies. I was definitely thinking of the time period before work started on Golly 2.8, but that didn't come across very well...!

I should probably also apologize for duplicating tired old ideas -- I don't have a clear recollection of when, but no doubt I've brought up many of the following points in golly-test at one time or another.
Andrew wrote:Are you just talking about zooming in, or zooming out as well?
The smallest improvement that would be useful for editing would be a Preferences checkbox to turn on zoom animations. It might still only be possible to stop at integer zoom levels, for selection and drawing purposes, but with a few intermediate frames, it would be easier to keep track of subpatterns as you're zooming in on them.

I'm not sure if that's worth the effort by itself, but maybe if it came along with a few other ways of reducing zoom-induced jerkiness? Following a growing spaceship or a spacefiller with Autofit in Golly is currently a somewhat painful experience, due to the instantaneous zoom changes.

Even following a regular spaceship with Autofit turned on is fairly strange, because the pattern only recenters, very suddenly, when it touches an edge of the view. LifeViewer's TRACK and TRACKBOX come to mind (of course).
Andrew wrote:[Zooming out] would require a major rethink given that Golly can zoom out to ridiculously large scales.
Yeah, the zoom-out problem is a whole different ball of wax, as Andrew points out. At least with fractional high-level zooms there'd be no need to worry about selections or mouse clicks. The biggest editing-related difficulty is the sudden mysterious color change for multistate rules when you zoom out past 1:1.

Maybe the 1x1 grid trick would be okay as a Preferences option, up to some cutoff size for the grid -- to allow interpolation of more or less the right colors down to 2^1:1 and 2^2:1, possibly?

I'd expect 2^1:1 colors to be useful much more often than 2^2:1 colors, and 2^2:1 colors correspondingly more often than 2^3:1 colors, and so on, so even interpolation for an extra zoom level or two would be a fairly significant improvement.

Propagating color up to arbitrarily large hashtiles would be a huge, Golly 3.0-worthy change, but it does seem like a possibility. Any fractional-zoom interpolation could be based on a larger grid at on the next lower zoom level, meaning dealing with up to four times the number of pixels that Golly currently has to handle anyway.

Re: Life tag testing

Posted: September 14th, 2016, 10:20 pm
by Andrew
If the goal is to make Golly's zooming/scaling more like LifeViewer then there might soon be a way to do it that doesn't involve modifying Golly's code. For the last few weeks I've been working on a new feature I call the overlay. It's essentially a rectangular chunk of pixels that can be displayed (optionally) above the current layer. Scripts have total control over the pixels in the overlay via a single new scripting command called "overlay". Here's a trivial little script that creates a small translucent blue rectangle in the middle of the current view:

Code: Select all

local g = golly()
local ov = g.overlay
ov("create 100 80")
ov("position middle")
ov("rgba 0 0 255 128")
ov("fill")
g.setoption("showoverlay", 1)
I've implemented various overlay primitives for drawing pixels, lines, text, etc. I'm also working on a new "oplus" module that uses the primitives to create high-level functions for creating buttons, sliders, etc. For example, here's the result of a new version of pop-plot.lua:

http://www.trevorrow.com/golly/popplot.png

And here's the result of another script that draws a true hexagonal grid above a layer that uses a rule with a hexagonal neighborhood (I've cloned and tiled the layers so you can see what's under the overlay):

http://www.trevorrow.com/golly/hexgrid.png

I'm reasonably confident that it will be possible to write a LifeViewer.lua script that would allow users to zoom/scroll/track patterns in the same way as LifeViewer. Probably not as fast as the web version but I'm very happy with the performance I'm seeing so far. Definitely not "inexcusably inefficient". :wink:

Re: Life tag testing

Posted: September 15th, 2016, 6:50 am
by rowett
Andrew wrote:I'm reasonably confident that it will be possible to write a LifeViewer.lua script that would allow users to zoom/scroll/track patterns in the same way as LifeViewer.
dvgrn wrote:The smallest improvement that would be useful for editing would be a Preferences checkbox to turn on zoom animations. It might still only be possible to stop at integer zoom levels, for selection and drawing purposes, but with a few intermediate frames, it would be easier to keep track of subpatterns as you're zooming in on them.
I think we probably need to do both since they're different use cases. Andrew's Awesome New Overlay (tm) should be great for smooth playback but may not solve smooth editing.
Andrew wrote:Are you just talking about zooming in, or zooming out as well?
I was thinking about the LifeViewer zoom range: -16x to +32x. Further out than that revert to Golly's current method. Would also give the opportunity to revisit the Smarter Scaling algorithm.

On a not entirely unrelated note it would probably be fairly straightforward to add a command to Golly that would generate a webpage containing the current pattern and LifeViewer js and launch it in a browser...

Re: Life tag testing

Posted: September 15th, 2016, 10:53 am
by dvgrn
rowett wrote:On a not entirely unrelated note it would probably be fairly straightforward to add a command to Golly that would generate a webpage containing the current pattern and LifeViewer js and launch it in a browser...
Interesting idea! I could probably do that with a (rather long) Lua script right now -- again, no need to modify any Golly code.

EDIT: Ah, right, the wxWidgets renderer that Golly uses to display HTML is a bit too limited to handle LifeViewer. Here's a Python script that works okay on Windows, anyway:
makeLifeViewerpage.zip
Python script that opens a browser to run LifeViewer on the current pattern in the active Golly window
(64.47 KiB) Downloaded 10 times
Andrew wrote:If the goal is to make Golly's zooming/scaling more like LifeViewer then there might soon be a way to do it that doesn't involve modifying Golly's code. For the last few weeks I've been working on a new feature I call the overlay. It's essentially a rectangular chunk of pixels that can be displayed (optionally) above the current layer.
Wow! That new oplus-enhanced pop-plot.py makes it look like the overlay could potentially do most everything I've been wanting to do in Golly, in terms of temporary GUIs to collect information to feed to search programs,

The hexagonal-grid screenshot makes it look like the script can find out what the coordinates of the current layer's bounding box are, rather than hard-coding a rectangle size. How do mouse events work on an overlay rectangle? golly.getevent() never needed to care about any resolution smaller than a single cell, but it seems like pixel-level information will be needed to run the controls properly.
Andrew wrote:I'm reasonably confident that it will be possible to write a LifeViewer.lua script that would allow users to zoom/scroll/track patterns in the same way as LifeViewer. Probably not as fast as the web version but I'm very happy with the performance I'm seeing so far. Definitely not "inexcusably inefficient". :wink:
Ha, well, I'll try not to put my foot in my mouth quite so thoroughly again. I suppose I should have said "excusably inefficient"... was thinking about things like grid drawing, in Golly 2.7 and below.

----------------------------------------------

Almost entirely unrelated, but speaking of efficiency and editing:

Along with finally checking in all the new files needed to get back to a really cutting-edge pattern collection, I really should spend some time looking at how to make some of the editing operations more efficient. Large XOR pastes are a good candidate for optimization, of course -- it seems that was some of my own inexcusable work. But I've also been running into cases where Shift+Space and Ctrl+Space (Advance Outside and Advance Selection) might be doing a lot more work than they need to be.

Don't think I've ever written out the details before, but I've developed instinctive work patterns that avoid the problems. Here's an example:

- Start with a Caterpillar, and do

Code: Select all

import golly as g
g.select([2094,330151,264,570])
- Hit Shift+Space. The resulting operations (saving, copying advanced, saving cell changes) take several minutes. Haven't looked at the temp files, but it seems as if Golly has to do quite a bit of work to Undo that operation.

- Start again with an unmodified Caterpillar with the same selection. Hit Ctrl+X, Space, Del, Ctrl-V, pasting into the same rectangle. This takes a few seconds at most, produces the same pattern, and Undo runs fairly quickly. The extra "Del" is only needed if the outside pattern causes new cells to be born inside the bounding box. (Right?)

Not surprisingly, the behavior for Ctrl+Space can be similar with a very large selection, like

Code: Select all

import golly as g
g.select([0,0,4195,330429])
There isn't an easy keyboard-shortcut equivalent for this case, I guess. Clear outside, run one tick -- that's all pretty fast, but then you have to get the original outside pattern back somehow.

Anyway, it's totally unworkable to use Ctrl+Space -- tends to crash Golly on my system. But it's fairly quick to copy the rest of the pattern, remove it, run the whole pattern, then paste the missing piece back in.

Will try not to hijack the Life Tag Testing thread with Golly minutia any more -- just wanted to get that written down while I was thinking of it.

Re: Life tag testing

Posted: September 15th, 2016, 7:37 pm
by Andrew
dvgrn wrote:That new oplus-enhanced pop-plot.py makes it look like the overlay could potentially do most everything I've been wanting to do in Golly, in terms of temporary GUIs to collect information to feed to search programs
Yep, that was one of my main motivations.
The hexagonal-grid screenshot makes it look like the script can find out what the coordinates of the current layer's bounding box are, rather than hard-coding a rectangle size.
Correct. I've added an optional parameter to the g.getview command so we can get the pixel dimensions of the current layer's viewport via g.getview(g.getlayer()). A g.getview() call is now equivalent to g.getview(-1) which returns the dimensions of the total view window. The results are only different when there is more than 1 layer and they are tiled.
How do mouse events work on an overlay rectangle? golly.getevent() never needed to care about any resolution smaller than a single cell, but it seems like pixel-level information will be needed to run the controls properly.
Yep, g.getevent returns a new "oclick" event (with pixel coords) if the user clicks in the overlay (but only if they click in a non-transparent pixel; ie. alpha is > 0). There's also a new mouse-up event so you can detect drags. And I'll probably add a wheel event as well.

There's really no reason why the eventual LifeViewer.lua script couldn't do all sorts of editing tasks as well as smart zooming/scaling/tracking. The whole idea of the overlay is that people can create pretty much any interface they like.

(No time to look at your Shift+Space/Ctrl+Space problems at the moment. Leaving for a week's holiday tomorrow, so remind me later.)

Re: Life tag testing

Posted: September 15th, 2016, 8:04 pm
by rowett
Andrew wrote:There's really no reason why the eventual LifeViewer.lua script couldn't do all sorts of editing tasks as well as smart zooming/scaling/tracking. The whole idea of the overlay is that people can create pretty much any interface they like.
Awesome, then we can write a lua script that parses LifeViewer scripts.

Re: Life tag testing

Posted: September 25th, 2016, 7:50 am
by rowett
Build 215 is now available on the lazyslug server

Enhancements in this build:
  • [[ TRACK ]], [[ TRACKBOX ]] and [[ TRACKLOOP ]] now scroll more smoothly at low GPS
  • changed timing display to show load%
  • added a close button to the navigation menu for the standalone viewer
  • new allocation model for faster memory copy
    • memory allocations are now shown in help information
  • new script command [[ STATE1FIT ]] that forces autofit only to use state 1 (useful for [R]History)
    • hotkey shift and "s" to toggle
Fixes in this build:
  • error display wasn't hiding UI controls correctly
  • accurate "Life ended at" generation when using STEP > 1
The updated hotkey map is here

Next on the list is B0 emulation for isotropic non-totalistic rules

Re: Life tag testing

Posted: September 26th, 2016, 10:46 am
by rowett
I was *this* close to implementing B0 emulation for non-totalistic rules in LifeViewer.

Instead, I enhanced Golly's Generations support by adding Hex, Von-Neumann and non-totalistic Moore neighborhoods.

Re: Life tag testing

Posted: September 28th, 2016, 4:06 am
by rowett
As if by magic...

Image

... the shopkeeper appeared.

Re: Life tag testing

Posted: September 28th, 2016, 12:20 pm
by rowett
Anyone for THEME 1?

Image

Re: Life tag testing

Posted: September 28th, 2016, 12:39 pm
by dvgrn
rowett wrote:Anyone for THEME 1?
I prefer a THEME 4 costume for my patterns, Mr. Shopkeeper -- there's just something particularly awesome about those transient purple streaks.

It's impressive that oblique ANGLEs are rendering so well already! Looking forward to the next episode in this exciting series --

Re: Life tag testing

Posted: September 28th, 2016, 8:05 pm
by Andrew
rowett wrote:Anyone for THEME 1?
Looking good! How's the performance compared with the real LifeViewer? (And we really must try to fix the bug that causes the edit bar buttons to lose their bitmaps.)

Re: Life tag testing

Posted: September 29th, 2016, 2:17 am
by rowett
Andrew wrote:
rowett wrote:Anyone for THEME 1?
Looking good! How's the performance...
From the Lua level it was poor since the rendering involves reading potentially millions of cells and then drawing the number of pixels that fit in the viewport (which for 1000x1000 viewport is a million pixels). Using 'test-overlay.lua' on my machine (64bit Ubuntu virtual machine running on a Windows 10 64bit host, quad core HT i7-2600K@4.3GHz with 16Gb RAM), it takes 0.75 seconds to draw a million pixels, and that's without having to read any cells.

Instead the prototype adds an optional rectangle of cells (currently 2048x2048 cells) to the overlay and a new rendering routine in wxrender that can do the rotation and scaling of the cells in that rectangle to the overlay pixmap. In this way the Lua is the controller but the heavy lifting is done in the native Golly code.

There are other use cases also where I think it would be useful to have a rectangle of cells attached to the overlay. There's actually also a case for an additional overlay pixmap in this case. Rectangle of pixels -> lower pixmap. Upper pixmap (containing UI elements) rendered above.

Updating the viewport involves two operations:
  1. refreshing the rectangle of cells (if the generation has changed since last update)
  2. rendering the cells to the overlay pixmap based on current rotation and scaling
1. Refreshing the cells is still fairly slow since it needs to make many calls to algo->nextcell() and broadly scales with number of live (non-state 0) cells in the rectangle. Using the Generations->Fireworks pattern (since it's a good worst case since most cells are in non-zero state) with different plane sizes I get the following performance:

Code: Select all

Plane Size   Population   Refresh time (ms)
200x200      35,000       3
400x400      135,000      10
600x600      305,000      24
800x800      540,000      42
1000x1000    850,000      65
This could be significantly improved if the algorithms supported a getrect() call of some sort.

2. Rendering the cells to the overlay pixmap with rotation and non-integer scaling is quick and scales fairly linearly with viewport size. With a 1000x1000 pixel pixmap it takes 2ms to 8ms (depending mostly on rotation since that impacts the order memory is traversed and hence how efficiently the CPU caches are used).
Andrew wrote:... compared with the real LifeViewer?
Promising but early days. This is LifeViewer running in Chrome on Windows 10 with a 1024x1024 canvas with the Generations->Fireworks case from above. Note these times are total update time, not just rendering, so include the next generation computation also.

Code: Select all

Plane Size   Population   Total time (ms)
200x200      35,000       2-5
400x400      135,000      3-6
600x600      305,000      4-7
800x800      540,000      6-10
1000x1000    850,000      8-11
The time range is showing non-rotated vs rotated. LifeViewer uses an optimized renderer when it doesn't need to rotate (which is the common use case).
Andrew wrote:(And we really must try to fix the bug that causes the edit bar buttons to lose their bitmaps.)
Agreed, it's annoyingly intermittent!

Re: Life tag testing

Posted: September 29th, 2016, 7:23 am
by Andrew
rowett wrote:Instead the prototype adds an optional rectangle of cells (currently 2048x2048 cells) to the overlay...
Not sure what you mean by that. I assume it's all done in C++ code (in wxrender.cpp?) rather than via some new overlay command? I guess it will become clear when you commit the changes.
There's actually also a case for an additional overlay pixmap in this case.
I've been thinking along much the same lines. It could probably be implemented quite easily via two new overlay commands -- "push" and "pop" -- that would allow scripts to create a stack of pixmaps. That would make it easy to implement things like pop-up menus. The rendering code would display the stack from the bottom up.

Re: Life tag testing

Posted: September 29th, 2016, 1:16 pm
by rowett
Andrew wrote:
rowett wrote:Instead the prototype adds an optional rectangle of cells (currently 2048x2048 cells) to the overlay...
Not sure what you mean by that.
My requirement is to have a special type of overlay (perhaps in a stack of overlays) where the overlay contents are generated from some arbitrary view over an arbitrary rectangle of cells in the Life universe, rather than via drawing primitives.

The prototype implements this as follows:
  • wxoverlay.cpp/h
    • Extends the Overlay object so it can attach a rectangle of cells to the Overlay and a camera definition.
    • Adds some overlay Lua script commands to create the rectangle of cells and manage the camera.
  • wxrender.cpp/h
    • In DrawOverlay() detect if an overlay has an attached rectangle of cells and if so updated them from the universe and then populate the overlay pixmap from the rectangle of cells using the camera.
    • If an overlay does not have an attached rectangle of cells then just render it as usual.
The proposed new overlay Lua commands are:
  • cellmap x y wd ht
    • Creates a view over a rectangle of cells in the universe.
  • camxy x y
    • Sets the camera x and y position over the cellmap.
    • Default is the centre of the cellmap.
    • Returns the previous x and y position.
  • camzoom zoom
    • Sets the camera zoom from 0 (minimum zoom, -16x) to 1 (maximum zoom, 32x).
    • Zoom is logarithmic across the 0..1 range to give smooth visual zoom in and out.
    • Returns the previous zoom.
  • camangle angle
    • Sets the camera angle in degrees.
    • Default is zero degrees for no rotation.
    • Returns the previous angle.
Here is the prototype lifeviewer.lua, hacked from your pop_plot.lua:

Code: Select all

-- LifeViewer for Golly
-- Author: Chris Rowett (rowett@yahoo.com), September 2016.

local g = golly()

local ov = g.overlay

local viewwd, viewht = g.getview(g.getlayer())

-- whether generating life
local generating = false

-- camera defaults
local defcamx = 0
local defcamy = 0
local defcamangle = 0
local defcamzoom = 0.2

-- camera
local camx = defcamx
local camy = defcamy
local camangle = defcamangle
local camzoom = defcamzoom

--------------------------------------------------------------------------------

local function createoverlay()
    -- create overlay over entire viewport
    ov("create "..viewwd.." "..viewht)
end

--------------------------------------------------------------------------------

local function updatecamera()
    ov("camzoom "..camzoom)
    ov("camangle "..camangle)
    ov("camxy "..camx.." "..camy)
end

--------------------------------------------------------------------------------

local function resetcamera()
    camx = defcamx
    camy = defcamy
    camangle = defcamangle
    camzoom = defcamzoom
    updatecamera()
end

--------------------------------------------------------------------------------

local function createcellmap()
    ov("cellmap -1024 -1024 2048 2048")
end

--------------------------------------------------------------------------------

local function refresh()
    ov("update") --???!!!
end

--------------------------------------------------------------------------------

local function advance(by1)
    if g.empty() then
        g.note("There are no live cells.")
        generating = false
        return
    end
    
    if by1 then
        g.run(1)
    else
        g.step()
    end
    
    g.update()
end

--------------------------------------------------------------------------------

local function reset()
    -- reset the camera if at generation 0
    local gen = tonumber(g.getgen())
    if gen == 0 then
        resetcamera()
    end

    ov("cellmap -1024 -1024 2048 2048")
    g.reset()
    g.update()
end

--------------------------------------------------------------------------------

local function rotateleft()
    camangle = camangle - 1
    if camangle < 0 then
        camangle = 359
    end
    updatecamera()
    refresh()
end

--------------------------------------------------------------------------------

local function rotateright()
    camangle = camangle + 1
    if camangle > 359 then
        camangle = 0
    end
    updatecamera()
    refresh()
end

--------------------------------------------------------------------------------

local function zoomout()
    if camzoom > 0 then
        camzoom = camzoom - 0.01
        if camzoom < 0 then
            camzoom = 0
        end
        updatecamera()
        refresh()
    end
end

--------------------------------------------------------------------------------

local function zoomin()
    if camzoom < 1 then
        camzoom = camzoom + 0.01
        if camzoom > 1 then
            camzoom = 1
        end
        updatecamera()
        refresh()
    end
end

--------------------------------------------------------------------------------

local function resetangle()
    camangle = 0
    updatecamera()
    refresh()
end

--------------------------------------------------------------------------------

local function setzoom(zoom)
    camzoom = math.log(zoom / 0.0625) / math.log(32 / 0.0625)
    updatecamera()
    refresh()
end

--------------------------------------------------------------------------------

local function main()
    createoverlay()
    createcellmap()
    resetcamera()
    refresh()
    
    g.show("Hit escape key to abort script...")
    while true do
        -- check if size of layer has changed
        local newwd, newht = g.getview(g.getlayer())
        if newwd ~= viewwd or newht ~= viewht then
            viewwd = newwd
            viewht = newht
            ov("create "..viewwd.." "..viewht)      -- resize overlay
            refresh()
        end
        
        -- check for user input
        local event = g.getevent()
        if event == "key enter none" or event == "key return none" then
            generating = not generating
        elseif event == "key space none" then
            advance(true)
            generating = false
        elseif event == "key tab none" then
            advance(false)
            generating = false
        elseif event == "key r none" then
            reset()
            generating = false
        elseif event == "key [ none" then
            zoomout()
        elseif event == "key ] none" then
            zoomin()
        elseif event == "key , none" then
            rotateleft()
        elseif event == "key . none" then
            rotateright()
        elseif event == "key 5 none" then
            resetangle()
        elseif event == "key 1 none" then
            setzoom(1)
        elseif event == "key 2 none" then
            setzoom(2)
        elseif event == "key 4 none" then
            setzoom(4)
        elseif event == "key 8 none" then
            setzoom(8)
        elseif event == "key 6 none" then
            setzoom(16)
        elseif event == "key 3 none" then
            setzoom(32)
        else
            g.doevent(event)
        end
        
        if generating then advance(false) end
    end
end

--------------------------------------------------------------------------------

-- allow layers to be tiled or stacked???!!!
-- local oldtile = g.setoption("tilelayers", 0)
-- local oldstack = g.setoption("stacklayers", 0)

local oldoverlay = g.setoption("showoverlay", 1)
local oldbuttons = g.setoption("showbuttons", 0) -- disable translucent buttons

local status, err = pcall(main)
if err then g.continue(err) end
-- the following code is always executed

ov("delete")
g.setoption("showoverlay", oldoverlay)
g.setoption("showbuttons", oldbuttons)
If you're happy with the approach I'll check in the prototype changes.