Posted: 18th Jun 2007 23:52
All Righty, I followed the formula for handling QUEUEs based on the almost nonexistent documentation (hit F1, look for QUEUE, read the help sentence, and figure out how to use it? The QUEUE commands aren't even in the example/use files!) - then jumped over to the Live CodeBase to find what seemed to be an eloquent example here. Only it doesn't seem to work outside the example.

Let me show you what I mean. In a "Constants and Globals" file, I have made the following declarations:

+ Code Snippet
   GLOBAL DIM chunkData() AS DWORD     ` A place to hold data until it is needed...
   GLOBAL chunkLen AS DWORD            ` ...and the reported length of this "chunk"...


...then a little later on, in a "File Processing" code file, I wrote the following function:

+ Code Snippet
FUNCTION ReadChunkData()

   ` Gets the next chunk's data into an array,
   ` allowing for segmentation (safety) as well
   ` as keeping track of where in the MIDI file
   ` (data) we happen to be...

   LOCAL chunkVal AS DWORD
   LOCAL aggChunkVal AS DWORD
   LOCAL hMult AS INTEGER
   LOCAL cCnt AS DWORD
   LOCAL vCnt AS DWORD


   EMPTY ARRAY chunkData()
   chunkLen = 0



   IF (thisChunkLength > 0)

      FOR cCnt = 1 TO (thisChunkLength / 2)
         hMult = 2
         aggChunkVal = 0

         FOR vCnt = 1 TO 2
            chunkVal = MEMBLOCK BYTE(thisMIDI, filePointer)
            aggChunkVal = (aggChunkVal + (chunkVal * (16 ^ hMult)))
            INC filePointer, 1
            DEC hMult, 2
         NEXT vCnt

         INC chunkLen, 1
         `DIM chunkData(chunkLen)
         `chunkData(chunkLen) = aggChunkVal
         ADD TO QUEUE chunkData()
         chunkData() = aggChunkVal

      NEXT cCnt
   ENDIF

ENDFUNCTION


The remm'ed out code (DIM, assign) works fine. But what if I wanted to treat that array as a QUEUE? Well, when comparing *my* code to the CodeBase example, I didn't see any big difference - and this code will compile and run.

Until you access the queue/array.

+ Code Snippet
      ReadChunkData()
      PRINT "chunkData() Count: ", STR$(ARRAY COUNT(chunkData())), "  (", STR$(chunkLen), ")"
      FOR cCnt = 0 TO (chunkLen - 1)
         PRINT "     ", STR$(cCnt), ":", STR$(chunkData(cCnt))
      NEXT cCnt


...if you use the QUEUE instructions, which appear to work in the CodeBase example, you always get the error 'Applicatio Error - The instruction "0x02731082" referenced memory at "0xfffffff4". The memory could not be "read". [OK][CANCEL]'

...but if I use the other code (DIM, assign) it works just fine. Am I to understand that the QUEUE has to be formatted or somehow linked/modified/processed in order to work right? Because you'd think it would work, given the fact that I followed the example's "flow" for the most part...

Aaaarrgh! So, what did I miss?
Posted: 19th Jun 2007 0:23
F1/Help -> Principles -> Lists,Stack and Queues

I didn't see your code call ARRAY INDEX TO QUEUE

might help, dunno
Posted: 19th Jun 2007 3:22
That's what you meant!

Look in the manual, its in there. Its in the help, too, but not so obviously. Cool huh?

I don't use them that way, however...I just use them.
Posted: 19th Jun 2007 4:02
Oh. Thanks. (Where might I find that documented?)

Not nit-picking, but ARRAY INDEX TO QUEUE is not used in the example from the live CodeBase, and if there are other examples where this is included, I'd like to know. I'm not a total noob, and it's still frustrating trying to figure out the docs on DBPro. [Shadows of "Hands On Dark Basic Pro Cost is Crazy"]

So, where should I put this, right where I initialize the array, or where I re-initialize (or clear out) the array before populating it?

Or does it matter?
Posted: 19th Jun 2007 4:03
Look in the manual, its in there


There's a manual? Where would I find that? This could be important...
Posted: 19th Jun 2007 4:33
Ummm, idunno. Its a little hidden, lem'me look....STBY, I'll edit this in a tick.

Name of file = U55-Manual-190704.rtf, located in root directory of DBPro CD, but I got a printed copy, as well. Its OLD, but there is a lot there, I use it alot. Like I've said elsewhere, I prefer printed docs to ones I have to have open while I develop. I already have VisualStudio, its help, and sometimes DirectX docs, and other SDK docs, its a mess. Like I also said, I prefer to build forts with my docs, and just leave room for my coffee and sundries.
Posted: 19th Jun 2007 7:46
Ah, thank you. I also have the CD Copy, but no printed manual, so was unaware of its existence. I will have this critter cross-indexed shortly, and readily accessible for on-line operations in two shakes...

I envy you, as I eventually gave up on having all the printed editions handy, and instead became proficient at fast-window-swapping, so now I have several windows open at once during the development cycle. And - up until tonight - I only had the Help.html files to work with, and they're pretty dodgy at best. Not complaining - I accept that the Forums know all.

Gad, it seems like we're all members of the same Lodge, only I haven't a clue as to how to gain status. For every question it seems that I am capable of answering, I ask two or three myself. That way lies bankruptcy, I'm afraid...
Posted: 19th Jun 2007 14:29
At the current rate of exchange, I'd say you were in the black, or red, or whichever one means you've contributed more than you've taken.

On that same subject, the only complaints I have about the help in the apps from TGC/et al is that, the way help is implemented in them, you can't really do that in the app. It is a little frustrating, so I use the manual alot, despite its age. WordPad format totally stinks, but it is still a good reference for me. The cross-indexing is a great idea, I just scroll and squint. The stuff that is HTML based does not suffer from that problem.
Posted: 19th Jun 2007 15:02
Check out my codebase entries - there are examples of queues, stacks and lists that I posted years ago there that will help you out
Posted: 19th Jun 2007 15:18
@IanM - I must apologize to you. I had looked at them, and I did not mention them, because I still don't use them that way...I'm drilling upwards at present. The 32 bit CRC is mantle, I'm nearly there. Also, I think that the evolution of your own plug-ins is something that should be examined by those wishing to make their way down a similar path. At any rate, it is all top-shelf stuff and I apologize for not mentioning it.
Posted: 19th Jun 2007 17:04
Waaah. <Sob!> It turns out I have DBPro CD V1.05, and apparently it was no longer distributed on the CD at that time...

Ah, well. I've still got the Forums, so I should do all right. Thanks, guys!
Posted: 19th Jun 2007 17:07
@TGC/MODS - Surely you will allow me to post this document?
Posted: 19th Jun 2007 17:43
Name of file = U55-Manual-190704.rtf, located in root directory of DBPro CD


I can not find the manual on the CD, but I have got a printed manual somewhere that came with my boxed version of the software. I refer to as an unsorted command list, but I don't miss it. I refer to the online help because it is easier to find what I need; at least if I know what I am looking for.

I have spent the morning so far downloading tutorials from the code base; mostly those produced by Mike (Yellow). They are examples of what a good tutorial should look like. Lots of comments and explanations of what is happening in the program, and DBP language explanations.

Just for the record, my boxed version shows 105 (same as Longfist), and was purchased at CompUSA.
Posted: 19th Jun 2007 17:52
I don't get it. I was using TinTin's example originally, because he used both Queues and Stacks in his code, and I used his techniques, and they work for his example, but not for my project.

Then I looked at IanM's examples, Stacks, and I find that they both do the same things. The same things that TinTin was doing...

Which amounts to:
+ Code Snippet
   DIM x() AS &lt;whatever&gt;
   EMPTY ARRAY x()
   ...
   ...
   ADD TO QUEUE x()
   x() = &lt;whatever&gt;
   ...
   ...
   IF ARRAY COUNT ( x() ) &gt;= 0
      PRINT "The queue has "; ARRAY COUNT( x() ) + 1; " items"
         FOR i = 0 TO ARRAY COUNT( x() )
            PRINT "  Item "; i; " = "; x(i)
         NEXT i
   ELSE
      PRINT "The queue is empty"
   ENDIF
   ...
   ...


...this is the pattern that QUEUES and STACKS use interchangeably. And IanM goes so far as to say,

No example of the 'array index to queue', because there is simply no need for this command (in my opinion). All it does is set the current index to the first item of the array, and you can get that value yourself by accessing array(0).


...so, let's see. <<Referencing the code included in my first post.>> In my code, I'm making an empty array of DWORDs, that I might create a QUEUE of MIDI two-byte directives. I make sure that - before we start working with the array - it has been emptied by the requisite "EMPTY ARRAY chunkData()". So the first two items have been accomplished. Later on, I "push" the items into the queue using the statements "ADD TO QUEUE chunkData()" and "chunkData() = aggChunkVal". Those two statements are right next to each other, in order.

So far, so good. But when I try to access the array, like in the other code modules, I get the 'instruction "0x02731082" referenced memory at "0xfffffff4"' error. That would be at the line where I try to determine how many array elements there are: "ARRAY COUNT(chunkData()".

Shouldn't this work? If so, what did I miss? If not, then why not? I'm confused... ...but the examples work, so this should work...
Posted: 19th Jun 2007 18:48
...which is one of the reasons I just use the array in a dimensionless manner. The index is below zero in your example, I think. I usually start out with if array count(blah()) > -1. Array count returns the next index, which is not the same as the count of elements in the array anyway.

What I am saying is that I create them using array insert at bottom, and I always empty them before using them at all. I never use queues, or stacks, so I guess I use them as lists. You can iterate through them in any direction or randomly, as long as you frame all of this with sensible use of array count and array index valid.
Posted: 19th Jun 2007 19:19
Aaah, Frobotzenshnaffels! I knew it was too good to be true. <grumble> Guess I'll go back to my literal handling of arrays - the old standby that never fails.

I can simulate the QUEUE operation by simply counting up from the first array element, and all will be well.

Thanks guys - truly - I'm glad this doesn't just affect me!
Posted: 19th Jun 2007 19:19
and I find that they both do the same things

Not at all really. Queues push new items onto the front and remove from the end. Stacks push items onto the end and remove from the end.

This means that you get items from queues in the same order that you pushed them (First In First Out - FIFO), and you get items from a stack in the reverse order that you pushed them (Last In First Out - LIFO).

You also need to define your array properly by running the dim command - it's not enough to simply have it in your source code somewhere. Arrays use 2-stages of initialisation. The first stage during compilation tells the compiler that the array exists and it's type. The second stage during runtime allocates memory to the array.

The error you are getting was fixed a long time ago - upgrade!
Posted: 19th Jun 2007 20:18
<glances at IanM>
I'm running Upgrade 6.6b - had to in order to make Wolf's Animation plugin work. Or was this fixed just recently? I'll go check to see if this is, indeed, the latest version. 21st of March, 2007 appears to be "the one"...


You also need to define your array properly by running the dim command - it's not enough to simply have it in your source code somewhere.


<frustration mounts, head explodes>

Okay, I'll bite: when *do* these little things happen? I'm not too clear on it for DBPro, which seems capricious at best. In C++, you define your arrays/variables/constants first, then use them. In DBPro, you define/use your arrays/variables/constants whenever? Or maybe you should define them all in the head of the initial file, in the hopes that the compiler perhaps will see them and grant them some small space on the far heap?

Make some sense of this: when I use the direct array approach:
+ Code Snippet
   INC chunkLen, 1
   DIM chunkData(chunkLen)
   chunkData(chunkLen) = aggChunkVal

...the code works! And if I do it using QUEUES, it fails. So, I'm to understand that the variable definitions that are included in another file, GLOBAL in scope though they be, are useless? Heh, maybe Dijkstra was onto something when he said what he said about BASIC programming.

Perhaps I spent too much time coding in C/C++ to make sense of this, so can somebody tell me the order of compilation? It is all too clear to me now what is happening: the compiler has absolutely no clue where anything is, or what the scope of it might be - there is no structure for it to follow - so for some unknown reason the compiler does not touch the included structure file until it reaches a #CONSTANT that it does not understand. Up until then, it "makes it up" as it goes along. Can't find the instantiation of the ARRAY of chunkData? Make it up (instantiate it) on the spot - making that array local to the FUNCTION! Then, after returning from the function, the *rest* of the application is left in the dark. Dark. BASIC. Fitting.

!!


<snickers at self> <snickers again at self>


I've written a few compilers in my time. I wonder why I missed *that*, it was staring me (quite literally) in the face. I must be slipping...


<wipes face with hand, inhales deeply>
<cools down, gets a grip, and becomes normal again>
<...well whatever passes for normal - with LongFist, you never know...>


I'm sorry - this is my official apology for sending you guys running round and round trying to figure this thing out. Here. I'll spell it out for you, because I must admit that I'm not making too much sense.

The compiler arrives at the FUNCTION ReadChunkData(), and plunges in. Now, it doesn't matter that - in another file - there is a GLOBAL definition for 'chunkData' as a DWORD. (Which makes me wonder how in the world it treats other GLOBAL definitions in the program.) It just rolls right in there, and encounters the statement "ADD TO QUEUE chunkData()" and tries to figure out what I mean by that. I no longer assume it checks a resource hash to determine if such a thing exists: it apparently creates a local array called "chunkData" of what type I can only imagine, the default probably being INTEGER unless I miss my guess. It then goes through the motions, adding data, adding data, etc. Then, the FUNCTION ends, and all LOCAL data is removed from the stack - the impromptu chunkData array along with it. The instruction pointer returns to the main segment of the program, and when the array is accessed - since it wasn't really played with at all - a fatal exception is generated, because the program has attempted to read data that isn't there. In fact, the pointer to that array hasn't even been instantiated yet, so it points to some default location "0xfffffff4" or other. Regardless, the app crashes, spits up a "send/don't send" dialog for Windows, and dies.

But get this: if I use the DIRECT array manipulators, NOT the QUEUE commands, the compiler acts in a different way. Somehow, by using the DIM command to resize the array, the compiler mystically becomes aware that - one file over - there is a GLOBAL definition for that very same ARRAY, and everything works perfectly, right down to being able to access the data --- inserted into the Array within the FUNCTION --- as the GLOBAL data that it is.


<...can anybody see where an experienced developer might be frustrated?>


I was confused, but now I am not. If you intend to use structured, methodological development styles (like are employed in C, C++, Pascal, Java, etc.) with DBPro, you're in for a LONG, LONG road. A long, and possibly frustrating journey, I'm afraid. But at least now I think I understand, and this might make me even more useful to others in the future... ...after all, there is no knowledge that is not power...


Thank you guys for your time and patience. I'm sorry if I managed to upset anyone - that was never my intention. My frustration was just getting the better of me, that's all. And as a businessperson, you'd think I had better self control, now wouldn't you? For shame. Please accept my apologies. Thank you for your time and consideration. I will rant no more.
Posted: 19th Jun 2007 20:59
Ok, I really don't know what you are doing wrong because these commands are really simple to use.

This doesn't crash:
+ Code Snippet
` Note, the flow of processing runs through this line and allocates the memory (just enough to hold the array info in this case, with no elements)
DIM chunkData()

` Add a new item to the queue and set its value
add to queue chunkData()
chunkData() = 1

` Add another item
add to queue chunkData()
chunkData() = 2

` and one more
add to queue chunkData()
chunkData() = 4

` Now remove them one by one
while array count( chunkData() ) &gt;= 0
   print chunkData(0)
   remove from queue chunkData()
endwhile
print "All done"

wait key


If you are not allocating memory for your array (as noted in the remark) then this might cause your problems, but if that's not it for you, then I really don't know what you are doing to cause it.

[EDIT]Now I've read your post properly, I know what's going wrong. It appears that there's a bug with the compiler - it should give an error with the two declarations of the chunkData. Multiple DIMs of the same array is OK, using the same name for a variable or declaring the variable as global twice should cause an error.
Posted: 20th Jun 2007 1:19
If I were to DIM the array again, in the FUNCTION, do you think it might hammer out the problem? I'm not at that desk, so I cannot test it and tell you what might happen. x

But, yeah, an error telling me about it would have been cool.