LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Ways to handle data.

Root / Programming Questions / [.]

raimondzCreated:
Hi, I was trying to encapsule behaviors in a bullet hell using data. And done a demo by recreating undertale bullet hell system on smilebasic. Now I'm facing a problem: 1-I have a lot of repeated data. I know that a technique is to inherate data from a base pattern and then do small changes... but this lead to the problem 2 2- Calling Restore or spanim cause after another call of Restore cause the lose of data from the first one. This is a simple example:
@pattern1
Data "create_bullet", 240,100 //Create a bullet
  Data "animate_bullet","I","@pattern2",0 //Set an animation to previous bullet
Data "create_bullet", 220, 100 //Create another bullet
Data "another_command"
...
Data "end"

@pattern2
//Here go data code according to SPANIM.
In the previous example, everything from the line animate_bullet is lost because the queue of data is remade using the data of @pattern2 If I store a base pattern then the same will happen. I thought of using copy to store data in an array but it only allow one type. Anybody know a library to handle data? or a Strategy to handle this scenario? By the way, the key is KA5D4T3. Use konami code while playing to see different behaviors.

I thought of using copy to store data in an array but it only allow one type.
The ugly solution that first pops to mind is to use two arrays: one for numeric and one for string.

I also thought about doing something like that but the problem with that is that the data must follow an strict scheme because the READ operation cannot tell you if you're reading string or number. My options right now is to handle everything as String and using Val to get the number. I thought about using number but: -Debugging data without any string isn't easy because you couldn't know what could be wrong if something fail. -Labels cannot be added on the data and must be hardcode through an array. I'm gonna try to use the option with string, but if anybody has a better solution or an idea, then let me know.

Well, taking Square's idea a bit further, this could actually work. The program needs to know what type to expect in a READ anyway, so you could just PUSH string READs to a string array and PUSH number READs to a number array. This will definitely have some overhead and might noticeably affect performance, or it may not. Some example code, completely untested and may have bugs and/or typos.
RESTORE @LABEL
WHILE TRUE ' there's a BREAK later
   READ S$ ' string defining the type of info to follow, e.g. "create_bullet"
   PUSH READSTRINGS$, S$
   IF S$ == "end" THEN BREAK
   ' Figure out how many inputs this command takes, place this in C%
   FOR I = 1 to C%
      ' figure out whether next READ is string or numeric
      IF NEXTISSTRING THEN
         READ S$ ' I'm reusing the S$ from before because I assume the old value is no longer needed
         PUSH READSTRINGS$, S$
      ELSE
         READ N
         PUSH READNUMBERS, N
      ENDIF
   NEXT
WEND

' When you need to use the info, you use:
S$ = SHIFT(READSTRINGS$)
' or:
N = SHIFT(READNUMBERS)
' and you can do them in the same order and logic as your current READs work.

This. So much this. I tried COPY but I need to give an array with the exact size of the input. However this is much better. However, I didn't use the type in my code since that would make twice the data. Instead, I have a system like json... "key: value" where value could be a string, number or another structure. It's up to my program to decide what type is used based on the key. Also, I don't think that there will be a noticable overhead since push, pop, shift and unshift should have computational complexity of O(1). (Also, I had a similar loop to decide the type of data that contain the key) This is the code I did:
DEF readLabel( S$ )
 DIM D$[0]
 RESTORE S$
 WHILE TRUE
   READ S$
   PUSH D$, S$
  
   IF S$=="END" THEN BREAK
 WEND
 RETURN S$
END

Does that work? You do have numerical DATAs in the example code in the OP. Admittedly I don't have the program yet, so I can't test a thing :(

Everything is a string but I handle number with VAL(String) For example, to resize the box on my demo from above, now I use:
DATA "BOX", "0"
 DATA "160","120","100","100","1","1"
Then, when I read the data, I do this:
COMMAND$=SHIFT(DAT$)
TEMP$=SHIFT(DAT$)
TIMEOUT=VAL(TEMP$)
IF COMMAND$=="BOX" THEN readBox
...
DEF  readBox
 VAR CLIP$
 CLIP$=SHIFT(DAT$)
 BX=VAL(CLIP$) //BOX POS X

 CLIP$=SHIFT(DAT$)
 BY=VAL(CLIP$) //BOX POS Y

 CLIP$=SHIFT(DAT$)
 BW=VAL(CLIP$) //BOX WIDTH

 CLIP$=SHIFT(DAT$)
 BH=VAL(CLIP$) //BOX HEIGHT

 CLIP$=SHIFT(DAT$)
 BCS=VAL(CLIP$) //BOX CHANGE SPEED. 

 CLIP$=SHIFT(DAT$)
 BOX_setClip VAL(CLIP$) //A FUNCTION THAT USE SPCLIP BASED ON THE BOX DIMENSIONS.
end
[CODE]

You can read numerical data do.