Norns: scripting

norns

#140

Thanks, I will try to follow your advice!

If I may ask one more question: With what you said in mind, what’s the recommended way when all I want to do is to make a 1:1 copy of a table into a different table, and all elements are numbers? From what I know right now, I’d probably still go with

for i = 1, #original do
copy[i] = original[i]
end

#141

As long as the elements are always simple the you are good with that code (& in fact you can see in my recent Contribution to foulplay.lua in dust I made the exact same choice for the same reason)

Assumptions are what catch you out so consider making that assumption explicit in a comment but as long as it is you and your code making the table in the first place I wouldn’t worry


#142

Ok thank you, those are very useful informations.


#143

as it happens, @Justmat just landed rotation for foulplay

might be a handy jumping off point? (and maybe something we should consider moving to a shared library.)


#144

I had considered putting the rotate_pattern() function in lib/lua/er.lua, but wasn’t sure. :sweat_smile:


#145

:+1:

if/when you want to copy more than just numbers, you might find these reflections useful: http://lua-users.org/wiki/CopyTable


#146

Yeah, @Justmat and I talked about this when I hacked together that rotate function.

Would we want to throw a github pull request up for adding utility functions like this to the libraries?


#147

+1 for (documented) additions to the library - much better to have single implementations of things that are well used (and therefore robust) and unless this kind of stuff goes in early you end up with all kinds of cut and paste or totally separate versions scattered throughout scripts…


#148

I agree, and especially in the case of rotate_pattern(). It seems like playfair could benefit from track rotation, as well as any other euclidean based scripts that come along in the future.


#149

What about adding something like penlight to the available Lua modules?

Lua utility libraries loosely based on the Python standard libraries

GitHub, Lua Rocks, API docs.

It provides copy, deepcopy and others.

(Caveat: I’ve never used it, but the principle of adding a more full featured standard library to Lua seems sound for our use case.)

It might be better to think about blessing certain existing Lua libraries for inclusion rather than us trying to reinvent the wheel. There is a list of the most depended on Lua libraries here: https://luarocks.org/stats/dependencies

If there is interest I can open up a ticket on one of the GitHub issue trackers (probably norns).


#150

Housekeeping for shapes drawn on grids and/or norns’s screen?

When doing my first steps in Lua with norns and grids, I wanted to
(a) draw shapes on the grid and
(b) interact with these grid shapes, i.e. detecting user pressing grid keys belonging to a shape, brightening or dimming a shape.

Being a rookie at this, I found that I have to do “double book-keeping” for this, i.e. I had to create (and maintain) these shapes in both function gridkey (x, y, z) and function gridredraw(). I found this to be error-prone, as I had to keep track of the coordinates of these shapes in both functions.

I guess I can overcome this by creating a function that simultaneously draws a shape and returns values if buttons belonging to a shape have been pressed.

Reading that the community is contemplating adding rotate_pattern() to the norns’s Lua library, does it make sense to add functions to norns’s Lua library that draw shapes onto the grid and/or norns’s screen? Or do these already exist and I just did not search for them thoroughly? Or is this double housekeeping expected?


#151

so regarding the two functions - they are separate, do separate things

I would expect you have a single data structure and then that is referenced by each function - one to detect key presses and one to enable the draw

excuse the pseudo lua

shape[64] = {....} 

function gridkey(x,y,z) 
      if shape[ convert_to_index(x,y) ] == 1 then
           .... do thing.....
      end 
end

function gridredraw() 
     for i = 1,64 do
        x,y = index_to_coords(i)
         if shape[ i] == 1 then
              ... colour in grid element x,y
         else
             ... turn off grid element x ,y 
         end 
     end
end

this assumes you have a function that draws shapes into shape by setting 1 (in shape) or 0 (not in shape) into the shape array.

There are two assumed functions to convert x,y to a single index and vice versa (pauses briefly to exclaim 1 based indexes!!!

(edit - where is all my indentation! ugh - added back ticks - nice - thank you @jasonw22 )


#152

Start your code with three backticks ``` and then end it with the same. This will give you a monospace font and the block between the backticks will preserve whitespace.

Perfect
    for
        poetry
   && code as well

#153

Thanks much again!

Please let me paraphrase this to see where I got it wrong:
• there are different shapes that shall be shown at different grid positions
• there’s a function write_to_shape_array(desired_shape, x, y) that writes one of these shapes at specified grid coordinates into the shape array
• now the shape array contains the state (lit =1, unlit = 0) for each button of the grid for the desired shape at the desired position, so that…
• …function gridkey(x,y,z) can test if an absolute button position is inside or outside of the desired shape, and…
• …function gridredraw() can light up the buttons at absolute positions for the desired shape.

As I only briefly attempted to understand some of the opinions on this topic, I guess I should keep my mouth shut, but…as the grid x/y coordinates are also 1-based, this seems to be at least matching, no?


#154

Your paraphrase is good - basically we make a bitmap of the grid and test against it - pinched from very old school game techniques (very old :wink: )

I’m a C programer originally (well my first job was as a Lisp programmer) and pointer/array arithmetic works better with 0 based array indexes. 1 based is weird! (but may make a lot more sense to a new programmer - I’ve no idea really - it is so ingrained in me that arrays are zero based )

Edit - do be clear what I’m telling you is just one way of doing things. A lot of developers have the view that their way is the one true way. Learn it like this because I learned it like this. I’m just sharing my thoughts since I am learning Lua/Norns etc myself at the moment so interested what people are up to. If you have a way that works better for you - go for it. But, for me personally anyway, I find examples of how other people are doing it quite useful for learning


#155

Is loading the next script the only occasion on which cleanup() is being executed? Or is it also executed when putting norns to sleep? If not, is there a function that is executed when putting norns to sleep?


#156

yes it is indeed indeed


#157

i would support adding penlight to the standard norns system, with mild reservations.

opened GH issue for deeper discussion [ https://github.com/monome/norns/issues/479 ]


#158

What is best practice(s) for adding a secondary function on a key in norns? For instance the way a long press on key 1 can be used inside a program, but all the short presses take you to the norns menu.

I’m guessing it’s something like starting a timer on key down, basing a short press on the key release (before a specified time let’s say 250ms) which kills the timer and registers a short press, and if the timer gets to its destination it registers as a long press?

Additional question, is best practice for this using a single tick metro or is there a simpler solution?

thanks!


#159

question: I’m writing something using the glut engine (@artfwo) - this may be a more general thing but I’m unfamiliar with the SC side of things at this point… is it possible to set the file “sample” param with a command (similar to params:set_action("cutoff", function(x) engine.cutoff(x) end))? or do files always have to be selected from the menus?

I have a function that chooses a file name from tape at random, hoping to be able to set it this way.