Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Newcomers DBPro Corner / Classes: Creating custom classes with arrays and static resources using coroutines

Author
Message
Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 19th Apr 2013 07:34 Edited at: 1st May 2013 13:16
Someone recently posted a question about defining UDT arrays in a function. Well, here is something along those lines, yet way more useful and good for object orientation.

Before long the procedural nature of the DarkBASIC professional array system brings you to the realization that the DBP command-set could really do with storing arrays in arrays, and functions in arrays. Afterall, in practical organization, lists often contain lists.

One work around is to use memblocks or Matrix1 banks to store arrays into other arrays. You can even store function addresses into arrays using the Matrix1 pointer system.

Another way is to store a long list of items which store links between themselves forming a series of items sharing common paths.

But how about a method which retains functions and arrays as they are without much conversion; do you always have to convert resources everytime you want to take advantage of object orientation, and the array system? Do you always need to use indexing to pair child items with parents and then iterate these lists when something needs to be removed?

No.. You do not have to always work with memblocks and you do not have to use link lists. Although there is nothing wrong with the combination.

However, one of the most overlooked features of Matrix1 utilities is the coroutine feature. Coroutines are functions which can process their actions and yield the program flow to other functions and the main loop without loss of information. These sub-programs are often used to operate primarily with local variables. They tend to be used for processing, but like I always say regarding tools; it's not what it is called, it's what it does that counts.

Coroutines can also be used as class instances that contain static storage in the form of local arrays and variables, which inturn can produce inner coroutines, thus members of their own. Much like memblocks being able to store arrays; it is possible to store arrays in these functions, and more interestingly treat functions as if they where array elements; since coroutines are numbered resources.

In the following example, two classes of coroutines store and update instances of a type called character. One of the classes has the ability to save, the other class only updates. The main program communicates with globals, and can also communicate with resources such as memblocks and images.



Now you are limited to 4096 coroutines and 2GB of RAM for 32bit apps; so this requires smart thinking and economy. Now 2GB ram for a video game is fine, but 4096 instances of a class would be too small to contain a medium to large game; better to treat these routines as classes themselves which store all their instances; for example if it is possible to have more than 4096 different entities in the application at once, make entities more comprehensive, each class function can handle various kinds of entities with similar properties.

Compared to types, you have the increased freedom of being able to do pretty much anything you can do with DBP inside of a class function; this means such classes can be composed of variable parts, yet share functionality with composite functions and use property functions to enumerate or transform resources all inside of a class function.

So coroutines are great for multi-processing; but for DBP they're also a solution for storing and dealing with complex information using similar types and parameters.

Uses for class functions include
* Game levels that can switch without being unloaded, and be unloaded when complete.
* Styles used to decorate how information is drawn
* Entities with customizable behaviour
* Multi-level hierarchies
* Speedy data access using locals

Remember to consider using the stack-size parameter of the coroutine constructer to allocate enough memory for your arrays and datatypes.
See the Matrix1 documentation.

You can check the memory size of arrays by converting them to memblocks. You can allow other functions to communicate with an array instance in the coroutine stack using array pointers and array linking.


GIDustin
15
Years of Service
User Offline
Joined: 30th May 2008
Location:
Posted: 24th Apr 2013 00:23
Are you sure this should be in the DBPro newcomer forum? Seems quite advanced...

Anyway, I have been using the Matrix commands save array to datafile/load array from datafile to save/load my UDT arrays to a file and haven't noticed any memory loss. Plus, the datafile commands are faster than DBP's file commands, and you are already using some Matrix commands so requiring those shouldn't be a problem.

I really need to look at coroutines more... I might be missing on some opportunities there.
Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 24th Apr 2013 03:23 Edited at: 24th Apr 2013 03:24
It's intimidating and complex when you look straight at, but if you read the snippet from start to finish you will find its not all that hard.

It's as easy as working with any resource; co-routines are a resource with an ID number, a size and a function name or pointer. A pointer is simply an address to something; a function pointer is the address to a function, much like a web address is a pointer to a server; just with number.

I posted this here because this answers many frequently asked questions; such as how to store functions in arrays, how to store arrays in functions, how to save arrays to file.

Now about that memory issue; I probably should have used the datafile functions instead, but didn't think to do it. Was busy talking about coroutines...

The issue sometimes occurs when converting the memblock to and from an arrays, not from disk.

Be sure to check out the Call Function Name and Call Function Ptr commands aswell; these allow you or the user to pick what functions to call at runtime.

Zero G Scott
16
Years of Service
User Offline
Joined: 14th Dec 2007
Location: California, USA, Earth, Sol Sys
Posted: 24th Apr 2013 21:52
Thanks for posting this Chris. In my current project I keep running into the same problem of associating lists of data to lists of data and creating what is essentially parent child relationships. So this looks incredibly helpful in learning a different way to associate the data more efficiently. Anything that helps me wrap my head around the basic tools of programming like coroutines and pointers helps me a great deal with where I am in my person knowledge base right now. I'm constantly picking up new bits of knowledge from your posts so thanks for being so open with what you work on.
Burning Feet Man
16
Years of Service
User Offline
Joined: 4th Jan 2008
Location: Sydney, Australia
Posted: 27th Apr 2013 10:26 Edited at: 27th Apr 2013 10:26
Why is the example code full of "\" slashes? Even with or without the slashes, I still can't get it to compile & execute. Could you simplify what's going on here, because I'm really interested in what you're trying to teach us here.

Help build an online DarkBASIC Professional help archive.
DarkBasic Help Wikia
Chris Tate
DBPro Master
15
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 27th Apr 2013 13:49
That is a forum error; I've done a search and replace on the snippet. Try again.

Login to post a reply

Server time is: 2024-04-19 01:23:08
Your offset time is: 2024-04-19 01:23:08