Using DATA to improve your program (Debug; Code readability; and more)
When programming, we want to make things as generic as possible so our tricks and "hacks" can work on any occasion we need them to. That's why we declare bunch of DEFs, bunch of generic variables and constants... All for that specific goal. But what happend if we want to go beyond generic code?
When i mean "beyond", i mean adding bunch of predefined pieces of code that allow us to have: Levels (on the most part); Menus... If you think about it, you would say something like: "Well, that can't go wrong". But can't be? Let's take a look.
Imagine we have a generic geim that has bunch of levels. When using the classic approach most users use when coding, it would look like this:
WHILE <Some Condition>
IF LEVEL%==1 THEN
IF LEVEL%==2 THEN
IF LEVEL%==3 THEN
Or something like this:
IF LEVEL%==1 THEN GOTO @LEVEL1
IF LEVEL%==2 THEN GOTO @LEVEL2
IF LEVEL%==3 THEN GOTO @LEVEL3
These two examples shares a common problem: It destroys code readability and makes it near impossible to debug if you end up adding like 30 segments of predefined code. So, what's the solution for this? The solution is using DATA.
What is DATA
DATA is the most closest thing SB will have to a "list" of arbitrary data. It allows us to encapsulate a set of predefined data together that we can access later, hence the name.
DATA <data 1>, <data 2>...
DATA "This is data",2,3.5,&HFF00FF00,&B0010,#UP
'Note: all the functions, including user functions, won't work on DATA. Since DATA only handles constant expressions
Accessing to the DATA
Accessing to the DATA is handled by READ command. READ gets the data in the order it's executed. If READ is executed for the first time, it will get the first data of a DATA set, if it is executed again, it will return the second data of the DATA set, and so on...
OUTPUT: 1DATA 1,2,3,4,5
So, if you want to access to the 5th element of a DATA set, you need to run READ 4 times before. So, on much cases you will end up using a FOR loop.
Locating the DATA set
You can "define" segments of DATA sets by using labels (@ABC) and the RESTORE command. Since DATA is being read from the very beginning of the source code to the end, RESTORE will define the start line so we can arbitrariely read what we want.
With this now we can start.
1.- Creating a DATA Parser
1.1.- What is a DATA Parser?
This doesn't have an official name, but i call it "DATA Parser" for the way how it works. On summary: a DATA Parser is a generic piece of code that can handle specific kinds of data and perform certain actions based on the data it receives. Pretty much like a DEF with multiple commands, with the exception that we don't need to call it over and over again, just give him the data it needs.
The structure of the DATA list will directly influence the way you setup the DATA parser. And the structure of the DATA list depends on what you want to achieve. Here, i'm going to use a very typical example: Showing a message.
Let's suppose i want to show a message on screen with the following arguments:
- Color of the message
- Duration in seconds
when using DATA, it should look like this:
' White message with a duration of 5 seconds
Now, we set an "ID" to the DATA segments we are going to use, by using a @Label:
With this setup, we can start making the DATA Parser.
1.2.- Setting up the parser
As explained early, DATA parsers are generic code, so we must do a code that can handle most, if not, all the possible parameters we parse to him. For this example, if we combine READ and RESTORE, we will get something like this:
DIM ARG$, DELAY%,GC,PREV_MILI%
'DATA Parser for messages
IF !DELAY% THEN
'I read the necessary arguments before showing anything. Yours can vary based on your needs.
'Clock in seconds
IF PREV_MILI%+1000 < MILLISEC THEN
Aaaaannndddd... Well, that's all, for a very simple reason: When the DATA Parser is ready, most of your editions will go on the DATA statements and not on the core structure. With that you can sepparate the logic from the arguments, and have a more cleaner code that will not only look "good" (every code is a mess, but anyways), but it will save you time when you want to make quick edits to the levels or the stuff you're showing.
What if you want to add or erase messages? Just add more DATA like this:
DATA "Me","This is a message using DATA statements (DUR: 5 secs)",&HFFFFFFFF,5
DATA "Me","Is amazing because i don't have to touch the core structure to add more and more (DUR: 5 secs)",&HFFFFFFFF,5
DATA "Someone else","Also, this message is plain red (DUR: 5 secs)",&HFFFF0000,5
DATA "Me","And this message last 3 seconds and is blue (DUR: 3 secs)",&HFF0000FF,3