Old 05-10-2019, 07:11 AM   #1
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default Short-handing Code in Lua?

Is there a way to short-hand the code below using an incremental variable to lessen the amount of times to compare items? For this example, increment every location where a '1' is typed??

Code:
	elseif string.starts(nameOut, "Special 1") then -- found 'Start' marker
		Song1SMarked = true
		Song1StartMarkerNum = retval
		Song1Title = MkrSegments[2]
		Song1Singer = MkrSegments[3]
		GUI.Val("Song1Tracks", 	MkrSegments[4])
		GUI.Val("Song1Scene", 	MkrSegments[5])
		Song1StartMarkerButtonText = reaper.format_timestr(posOut, "")
		GUI.elms.Song1StartButton.func = EditSong1Start
.
.
.
-- code pattern to repeat....
	elseif string.starts(nameOut, "Special 200") then
		Song200SMarked = true
		Song200StartMarkerNum = retval
		Song200Title = MkrSegments[2]
		Song200Singer = MkrSegments[3]
		GUI.Val("Song200Tracks", MkrSegments[4])
		GUI.Val("Song200Scene", MkrSegments[5])
		Song200StartMarkerButtonText = reaper.format_timestr(posOut, "")
Maybe something like:
Code:
	elseif string.starts(nameOut, "Special " .. i) then -- found 'Start' marker
		Song{i}SMarked = true
		Song{i}StartMarkerNum = retval
		Song{i}Title = MkrSegments[2]
		Song{i}Singer = MkrSegments[3]
		GUI.Val("Song" .. i .. "Tracks", MkrSegments[4])
		GUI.Val("Song" .. i .. "Scene", MkrSegments[5])
		Song{i}StartMarkerButtonText = reaper.format_timestr(posOut, "")
		GUI.elms.Song{i}StartButton.func = EditSong{i}Start
I've tried a few different variations, but either it's not possible, or I'm doing it wrong.
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-10-2019, 07:18 AM   #2
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 1,315
Default

Can you post some example-data that reflects the data you want to compare against?

The more systematic the sourcedata is, the more likely is it to improve it on a systematic level.
If the sourcedata is quite erratic, there's probably not much you can do.
__________________
Ultraschall-API - a Lua-functions-library4Reaper: https://forum.cockos.com/showthread....98#post2067798
Reaper Internals - Developerdocs4Reaper: https://forum.cockos.com/showthread.php?t=207635
mespotine is offline   Reply With Quote
Old 05-10-2019, 07:26 AM   #3
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default

Quote:
Originally Posted by mespotine View Post
Can you post some example-data that reflects the data you want to compare against?

The more systematic the sourcedata is, the more likely is it to improve it on a systematic level.
If the sourcedata is quite erratic, there's probably not much you can do.
I'm trying to figure out what it is that you are asking that hasn't already been provided in my original post. The 'example-data' is in my original post.
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-10-2019, 07:30 AM   #4
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 1,315
Default

No, it's example tables and code, but what I mean is: what is actually the value within the tables.

For instance:
GUI.Val("Song1Tracks", MkrSegments[4])
GUI.Val("Song1Scene", MkrSegments[5])

What values are stored in MkrSegments[4] and MkrSegments[5], etc?
And where does nameOut come from and what could be the value in that, that you want to check against "Special 1" and "Special 200"?
__________________
Ultraschall-API - a Lua-functions-library4Reaper: https://forum.cockos.com/showthread....98#post2067798
Reaper Internals - Developerdocs4Reaper: https://forum.cockos.com/showthread.php?t=207635
mespotine is offline   Reply With Quote
Old 05-10-2019, 07:36 AM   #5
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default

Quote:
Originally Posted by mespotine View Post
No, it's example tables and code, but what I mean is: what is actually the value within the tables.

For instance:
GUI.Val("Song1Tracks", MkrSegments[4])
GUI.Val("Song1Scene", MkrSegments[5])

What values are stored in MkrSegments[4] and MkrSegments[5], etc?
And where does nameOut come from and what could be the value in that, that you want to check agains Special 1 and Special 200?
Code:
-- Scan Markers for updates / changes
	mkr_idx = {} mkr_pos = {}  -- create mkr_idx and mkr_pos tables (arrays)
	mkr_name = {} mkr_num = {}
	num_mkrgns, num_markersOut, num_regionsOut = reaper.CountProjectMarkers(0)  -- count markers and regions in project

	if num_markersOut then   -- if markers exist...
		for i = 0, num_mkrgns - 1 do  -- loop through marker and region index nums
			retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut, colorOut = reaper.EnumProjectMarkers3(0, i)
			if not isrgnOut then  -- if not a region...
				mkr_num[markrgnindexnumberOut] = retval 	-- store marker number
				mkr_idx[markrgnindexnumberOut] = i -- store idx in marker idx table (not strictly necessary)
				mkr_pos[markrgnindexnumberOut] = posOut  -- store marker's position (time) in marker pos table
				mkr_name[markrgnindexnumberOut] = nameOut -- store marker's text
				MkrSegments = SplitStrH(nameOut) -- Split marker's text into segments separated by " - "
				NumSegments = tablelength(MkrSegments) -- Count the number of segments
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-10-2019, 08:01 AM   #6
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 1,315
Default

So if I get it right:
You want to check all markernames, if they start with "Special 1" or "Special 200", right?
And your current strategy is, first you check all of them for "Special 1" and then all of them for "Special 200"?

In that case I would suggest the following strategy:

1) Check if a markername begins with "Special". Yeah, no number, only "Special".
2) If yes, you secondary-check for "Special 1" or "Special 200", else you got to the next marker.
That way, you don't check all markers twice.

Depending on what is more likely to happen, you should order the secondary-checks accordingly. So if "Special 200" appears more often, you check that first, then "Special 1".
__________________
Ultraschall-API - a Lua-functions-library4Reaper: https://forum.cockos.com/showthread....98#post2067798
Reaper Internals - Developerdocs4Reaper: https://forum.cockos.com/showthread.php?t=207635
mespotine is offline   Reply With Quote
Old 05-10-2019, 09:07 AM   #7
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,021
Default

Quote:
Originally Posted by tXShooter View Post
Maybe something like:
Code:
	elseif string.starts(nameOut, "Special " .. i) then -- found 'Start' marker
		Song{i}SMarked = true
		Song{i}StartMarkerNum = retval
		Song{i}Title = MkrSegments[2]
		Song{i}Singer = MkrSegments[3]
		GUI.Val("Song" .. i .. "Tracks", MkrSegments[4])
		GUI.Val("Song" .. i .. "Scene", MkrSegments[5])
		Song{i}StartMarkerButtonText = reaper.format_timestr(posOut, "")
		GUI.elms.Song{i}StartButton.func = EditSong{i}Start
I've tried a few different variations, but either it's not possible, or I'm doing it wrong.
You've got the right idea, but you can only interpolate variable names like that when you're accessing a table. Lua also doesn't have real interpolation like most languages - you have to use .. to concatenate String .. Variable .. String. In this case, try:
Code:
_G["Song"..i.."Title] = MkrSegments[2]
However:

1. It's generally not a good idea to use global variables for everything. There's a performance cost, and you can leave yourself open to all sorts of complicated bugs because your variables are accessible from EVERYWHERE in the script.

2. Any time you're repeating the same structure, or you find yourself wanting to have a bunch of the same variables with an incrementing digit, a table is going to make your life so much simpler.

Code:
local songs = {}

... do stuff ...

...
elseif string.starts(nameOut, "Special " .. i) then -- found 'Start' marker
  songs[i] = {
    marked = true,
    startMarkerNum = retval,
    title = MkrSegments[2],
    singer = MkrSegments[3],
    startMarkerButtonText = reaper.format_timestr(posOut, ""),
  }
  
  GUI.Val("Song" .. i .. "Tracks", MkrSegments[4])
  GUI.Val("Song" .. i .. "Scene", MkrSegments[5])
  GUI.elms["Song"..i.."StartButton"].func = EditSongStart
  GUI.elms["Song"..i.."StartButton"].params = {i}
...
Also note that I've changed the name of EditSongStart so that all of the buttons can use the same function, and then they can pass their i to it as a parameter. Always try to make things reusable.
Lokasenna is online now   Reply With Quote
Old 05-10-2019, 09:25 AM   #8
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default

Quote:
Originally Posted by mespotine View Post
So if I get it right:
No offense, but... No, you don't.

Imagine the attached file (function) from my script, which is just one function. Now, imagine having about 20 or so very similar functions all typed out like that. Now, imagine that starting at line 878 in the attached file I have to modify all of the elseif string.starts from:

Code:
	GUI.Val("Song3Title", 	MkrSegments[2])
	GUI.Val("Song3Singer", 	MkrSegments[3])
to:
Code:
	Song3Title = MkrSegments[2]
	Song3Singer = MkrSegments[3]
and I also need to add into each 'elseif' section:
Code:
	if GUI.Val("Song1Microphone") == "1" then -- Determine Track Group Colors
		GUI.elms.Song1StartButton.col_fill = "brown"
	elseif GUI.Val("Song1Microphone") == "2" then
		GUI.elms.Song1StartButton.col_fill = "red"
	elseif GUI.Val("Song1Microphone") == "3" then
		GUI.elms.Song1StartButton.col_fill = "orange"
	elseif GUI.Val("Song1Microphone") == "4" then
		GUI.elms.Song1StartButton.col_fill = "yellow"
	elseif GUI.Val("Song1Microphone") == "5" then
		GUI.elms.Song1StartButton.col_fill = "green"
	elseif GUI.Val("Song1Microphone") == "6" then
		GUI.elms.Song1StartButton.col_fill = "blue"
	elseif GUI.Val("Song1Microphone") == "7" then
		GUI.elms.Song1StartButton.col_fill = "violet"
	elseif GUI.Val("Song1Microphone") == "8" then
		GUI.elms.Song1StartButton.col_fill = "gray"
	elseif GUI.Val("Song1Microphone") == "9" then
		GUI.elms.Song1StartButton.col_fill = "white"
	else
		GUI.elms.Song1StartButton.col_fill = "elm_frame"
	end
	if GUI.Val("Tracks") == "1" then ..........
Now, imagine having to modify several of the other extremely long functions.

What I'm trying to do is to shorten the amount of typing involved in creating / modifying these highly repetitive-like yet very long functions. Also known as 'short-hand', or 'short-handing' (or if you will, 'short-cutting').

It would certainly be nice if I could replace the common numeral (1-200) with a variable and loop through each 'elseif' section.
Attached Files
File Type: lua function ScanMarkers().lua (127.8 KB, 6 views)
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-10-2019, 09:32 AM   #9
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default

Quote:
Originally Posted by Lokasenna View Post
You've got the right idea, but you can only interpolate variable names like that when you're accessing a table. Lua also doesn't have real interpolation like most languages - you have to use .. to concatenate String .. Variable .. String. In this case, try:
Code:
_G["Song"..i.."Title] = MkrSegments[2]
However:

1. It's generally not a good idea to use global variables for everything. There's a performance cost, and you can leave yourself open to all sorts of complicated bugs because your variables are accessible from EVERYWHERE in the script.

2. Any time you're repeating the same structure, or you find yourself wanting to have a bunch of the same variables with an incrementing digit, a table is going to make your life so much simpler.
...

Also note that I've changed the name of EditSongStart so that all of the buttons can use the same function, and then they can pass their i to it as a parameter. Always try to make things reusable.
I'm ALL about making things simpler.

I thought there was a way to implement an incrementing table structure. I just couldn't see how to actually do it. I'm going to have to study your reply and see how to apply it to my script. It will likely change the entire script, which I may not be able to do in time for our conference next month (I have a limited amount of time to write this code between now and then).
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-10-2019, 09:32 AM   #10
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,021
Default

Quote:
Originally Posted by tXShooter View Post
Code:
	if GUI.Val("Song1Microphone") == "1" then -- Determine Track Group Colors
		GUI.elms.Song1StartButton.col_fill = "brown"
	elseif GUI.Val("Song1Microphone") == "2" then
...
Tables to the rescue!

Code:
local myColors = {
  "brown",
  "red",
  "orange",
  "yellow",
  "green",
  "blue",
  "violet",
  "gray",
  "white",
}

GUI.elms.Song1StartButton.col_fill = myColors[ tonumber(GUI.Val("Song1Microphone")) ] or "elm_frame"
Lokasenna is online now   Reply With Quote
Old 05-10-2019, 10:05 AM   #11
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default

Quote:
Originally Posted by Lokasenna View Post
Tables to the rescue!

Code:
local myColors = {
  "brown",
  "red",
  "orange",
  "yellow",
  "green",
  "blue",
  "violet",
  "gray",
  "white",
}

GUI.elms.Song1StartButton.col_fill = myColors[ tonumber(GUI.Val("Song1Microphone")) ] or "elm_frame"
Are you flipping kidding me?? It's just that simple? Man! I've been doing things the uber hard way for way too long not to have figure that out.

Thank you!!

Now I just need to figure out how to implement this style of coding without completely unraveling everything I've already got written, and without making my head explode (I'm the kind that can't seem to see the forest for the trees when it comes to coding).

Again, thank you!
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-10-2019, 10:22 AM   #12
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,021
Default

As a first step, the more consistent you can be with your existing style about typing it all out EXACTLY the same way EVERY time, then when you have time to refactor it you'll be able to do a lot of the work with a RegEx find + replace.

I had some similar code in my GUI that I was tidying up a few weeks ago, and I managed to do about an hour of replacing in ten minutes just because the duplicated code was almost identical each time.
Lokasenna is online now   Reply With Quote
Old 05-10-2019, 10:38 AM   #13
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default

Quote:
Originally Posted by Lokasenna View Post
Code:
local songs = {}

... do stuff ...

...
elseif string.starts(nameOut, "Special " .. i) then -- found 'Start' marker
  songs[i] = {
    marked = true,
    startMarkerNum = retval,
    title = MkrSegments[2],
    singer = MkrSegments[3],
    startMarkerButtonText = reaper.format_timestr(posOut, ""),
  }
  
  GUI.Val("Song" .. i .. "Tracks", MkrSegments[4])
  GUI.Val("Song" .. i .. "Scene", MkrSegments[5])
  GUI.elms["Song"..i.."StartButton"].func = EditSongStart
  GUI.elms["Song"..i.."StartButton"].params = {i}
...
Also note that I've changed the name of EditSongStart so that all of the buttons can use the same function, and then they can pass their i to it as a parameter.
.params = {i} would be what in this case? Or did you just tack that on as part of showing what else could be done with a table in this kind of setup?
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-10-2019, 11:11 AM   #14
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,021
Default

Your code in the OP appears to have a separate function for each song:
Code:
function EditSong1Start() ...
function EditSong2Start() ...
function EditSong3Start() ...
I'm guessing that they all do pretty much the same thing, just for a different song. If that's the case, the simpler approach would be to just have one function that takes the song number as a parameter:

Code:
local function EditSongStart(i) 
  doTheThingToSong(i)
end
The Button class' params is a table with any arguments you want to pass to .func when it runs. In the example I showed you the other day in the GUI library thread, I had .func calling the same function for all of my buttons and .params providing a different note number for each button.
Lokasenna is online now   Reply With Quote
Old 05-10-2019, 11:23 AM   #15
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default

Quote:
Originally Posted by Lokasenna View Post
Your code in the OP appears to have a separate function for each song:
Code:
function EditSong1Start() ...
function EditSong2Start() ...
function EditSong3Start() ...
I'm guessing that they all do pretty much the same thing, just for a different song. If that's the case, the simpler approach would be to just have one function that takes the song number as a parameter:

Code:
local function EditSongStart(i) 
  doTheThingToSong(i)
end
Many do have the same function.


Quote:
Originally Posted by Lokasenna View Post
The Button class' params is a table with any arguments you want to pass to .func when it runs. In the example I showed you the other day in the GUI library thread, I had .func calling the same function for all of my buttons and .params providing a different note number for each button.
That's what I was thinking, but wasn't sure for this example.
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-11-2019, 02:47 PM   #16
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default How do you Short-Hand the Functions?

Taking on the challenge of condensing things down with the usage of tables which Lokasenna introduced me to (thank you), I'm doing a Rev 3 re-write, and I've come across an conundrum. How do you assign functions that are similar, but still different? And conversely, how do you go about writing functions that are unique to each button's usage, yet still generic enough for a smaller script? Would I have to type out each and every function assignment as well as the actual function? (In this version I'm just going to do a total of 20 songs and 20 sermons, each with a Start and Stop button, instead of trying to do the 400 songs/sermons in my Rev 2 (that seriously got to be daunting and chaotic). A) So, am I looking at having to write a total of 80 functions for the 80 total buttons?)

Consider the code below.

When specific conditions are met, ie. all of the textboxes to the left of the 'Scene' textbox have valid information in them, the color for the Start button changes as well as the one to the End button (both to lime). So, when the 'Scene' textbox loses focus, a function validates the information to the three left textboxes and if valid it changes the color of the two buttons to the right. When one clicks on Start Special 1, the button's text should be updated with the position of the marker this button is creating, and its color is changed to a dull red while the other button is set to a bright red. When one clicks on the End Special 1 button, it's text also changes to the position of the marker it creates and changes the color of the buttons.

These functions can also be activated by the OSC input from a mixer console... if the mixer goes into a scene that matches one of the Scene textboxes, it calls the same function as the button that is assigned to that row of textboxes. Upon leaving that scene or manually clicking any other row's start button, the functions to other button are launched. The OSC input is the preferred method of placing a marker, but I need to allow for those manual moments as well.



B) How should I write the functions so that they respond correctly if clicked or OSC-activated out of sequence from the other Start/End Buttons? Can they be written generically and differentiate what called it? I'm still pretty new to Lua programming, so please forgive my ignorance.

{^^^^^ Too much information? ^^^^^}
Code:
-- ********** GUI Elements **********************
AllTabsY = {30,55,81,107,133,159}  -- Row Placement Y Values

SongTabCaptions = {"Title","Singer or Group Name(s)","Track(s)","Scn","Manually Edit Markers"}
SongTabsX = { 90, 430, 730, 880} -- Column Placement X Values
SongTabsW = {338, 298, 148,  40} -- Textbox Widths
SongTabsH = 25
MarkerButtonWidth = 110
MarkerButtonHeight = 20

-- Add Song Section to GUI
-- Tab 1 Labels Z = 12 Y = 25
function BuildGUI()
	-- Build Tab 1 Labels
	for i=1,5 do
		GUI.New(SongTabCaptions[i], "Label",{z=21, caption=SongTabCaptions[i], x=SongTabsX[i], y=30, font=2, color="txt",bg="wnd_bg",shadow=false})
	end
	-- Build Tabs 1 and 2 
	local Tab_Index = 1
	local b = 1
	for SongTabs = 1, 2 do -- Add GUI controls to Song Tabs 1 & 2
		local a = 1
		for Y= 1, 5 do -- Add 5 lines of Textboxes and Buttons for Tabs 1 and 2
			for X = 1, 6 do -- Add 4 Textboxes and 2 Buttons on Line 'a'
				GUI.New("SongTitle" .. a, "Textbox", {
				z = 11 + SongTabs
				x = SongTabsX[X], y = AllTabsY[Y],
				w = SongTabsW[X], h = SongTabsH,
				caption = "", cap_pos = "left",
				font_a = 3,	font_b = "monospace",
				color = "txt", bg = "wnd_bg",
				shadow = true, pad = 4,
				undo_limit = 20, tab_idx = Tab_Index
				Tab_Index = Tab_Index + 1})

				GUI.New("Marker_SongStart" .. b, "Button", {
				z = 11 + SongTabs,
				x = 930,  y = AllTabsY[Y],
				w = MarkerButtonWidth, h = MarkerButtonHeight,
				caption = "Start Special " .. a,
				font = 3,
				col_txt = "txt", col_fill = "elm_frame",
				func = StartButtonClick[a]})
	
				GUI.New("Marker_SongEnd" .. b, "Button", {
				z = 11 + SongTabs,
				x = 1040,  y = AllTabsY[Y],
				w = MarkerButtonWidth, h = MarkerButtonHeight,
				caption = "End Special " .. a,
				font = 3,
				col_txt = "txt", col_fill = "elm_frame",
				func = EndButtonClick[a]})
		end
	end
end

This is what I WAS doing until this posting helped to simplify several things. Hopefully I can keep simplifying things to a more manageable level.
Code:
function GUI.elms.Song1Scene:lostfocus()
	Song1SceneVal = GUI.elms.Song1Scene.retval
	if Song1SceneVal ~= nil or Song1SceneVal ~= "" then
		if ValidateSong1TextBoxes() then
			UpdateButtonColors(1,2)
		end
	end
	self:redraw()
end
function Song1StartButtonClick()
	GUI.Val("X32Scene","131")
	GUI.Val("Song1Scene","131")
	Song1SceneVal = GUI.Val("Song1Scene")
	X32Scene = GUI.Val("X32Scene")
	CheckScene(X32Scene)
end
How should I go about writing a generic function that does that function for each of the 'Start' buttons?
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-11-2019, 03:11 PM   #17
tXShooter
Human being with feelings
 
tXShooter's Avatar
 
Join Date: Aug 2017
Posts: 301
Default

Quote:
Originally Posted by tXShooter View Post
A) So, am I looking at having to write a total of 80 functions for the 80 total buttons?)

B) How should I go about writing a generic function that does that function for each of the 'Start' buttons?
Disregard ... I may have misunderstood something in this post.
__________________
"But be ye doers of the word, and not hearers only, deceiving your own selves."
tXShooter is offline   Reply With Quote
Old 05-11-2019, 03:45 PM   #18
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,021
Default

- Having smaller functions that try to only do one thing will make them easier to reuse in different situations. If you have a pile of very specific functions, you can combine them inside another function for your normal sequence of operations but still call them separately as needed.

- As far as allowing for different sequences, different ways to trigger parts of the logic, etc, the simplest way is to have one set of tables/functions that maintains the "state" of the script and make everything else use that. By controlling which parts of the script have direct access to the state, you can ensure that the state is always valid.

I've actually done a lot of work on the latter point with the GUI recently - the GUI's entire state was visible to the entire script, so the element classes were accessing it and modifying whenever they wanted. The more that happens, the harder it is to make sure everything is correct and avoid invalid states that might cause it to crash.

A good example of what you should (ideally, of course) be aiming for is the Buffer code from the GUI. Reaper has 1024 graphics buffers available, but if element classes can just pick whatever number they want things will start overlapping and getting messy very quickly. Instead, they rely on GUI.GetBuffer to hand buffers out - since there's only one function managing the buffers directly, there's no chance for confusion.
Lokasenna is online now   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 09:19 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.