Advertisement

Template containers angelscript addon library release!

Started by October 14, 2014 09:46 AM
48 comments, last by Wracky 8 years, 1 month ago
New iterator things!

iterator container::end() //returns an iterator that points at the end, useful for...
bool iterator::operator==(const iterator &in) //checking if your iterator equals end
bool iterator::IsEnd() //check it with 1 c++ function call and no need for creating another iterator object

bool container::erase(const iterator &in) //erase at iterator, returns true if something was erased (if iterator was not end)
size_t container::erase(const iterator_range_begin &in,const iterator_range_end &in) //erase a range, returns amount of things erased

//non map containers
iterator container::find_iterator(const value &in) //find that returns an iterator, returns end if not found

//vector and list
void container::insert(const iterator &in, const value &in) //insert before iterator, using end iterator will insert at the end

//map / uo_map
iterator container::find_iterator(const key &in) //find that returns an iterator, returns end if not found

.

As usual, you can change all the names in the config. If you don't like the nonstandard "value find(value,bool& success", you can name that to "nonstd_find" and name "find_iterator" to just "find".

No reverse iterators yet.

Also made some architecture changes to the c++ side of things, more templates, less nasty preprocessor names.
Theres a bit of a safety problem with iterators right now:
If a container is modified, all of it's currently existing iterators become invalid and using them will crash. I got some plans for more iterator safety, but it didn't make it to this build.
New stuff available in the new branch "experimental". ZIP

Nice work :)

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement

Implemented some form of iterator safety.


/*
  Every operation that changes a container increments a version number.
  If you try to access an iterator and it's version number differs from the container's, an exception will be thrown.
  Without this, illegal access will crash.
  This obviously reduces runtime performance.
*/
#define aatc_CONFIG_ENABLE_ERRORCHECK_ITERATOR_SAFETY_VERSION_NUMBERS 1
With this thing on, this code will cause exceptions instead of crashing:

vector<int> cont;

cont.push_back(1);
cont.push_back(2);
cont.push_back(3);
cont.push_back(4);
cont.push_back(5);

auto it = cont.find_iterator(3);

cont.erase(it);
cont.erase(it);//this line will cause an exception, because the previous erase modified the container

for(auto it = cont.begin(); it++;){
  Print("value = " + it.value);


  if(it.value == 4){
    //modify the container
    //this line will work here, but any iterator access or incrementing after it will cause an exception
    cont.push_back(123);
  }
}
You can custom tune your exception messages in the config:

/*
  Happens when trying to access or set an iterator and the container has been modified after iterator construction.
*/
#define aatc_errormessage_iterator_container_modified "Invalid iterator. Container has been modified during iteration."

/*
  Used by the container if it tries to use an invalid iterator.
  Example of erasing twice with the same iterator:
    vector<int> myvec;
    //add 1 2 3 4 5 to vector
    auto it = myvec.find_iterator(3);
    myvec.erase(it);
    myvec.erase(it);//this line will cause this exception, because the first erase changed the container state and invalidated all iterators
*/
#define aatc_errormessage_container_iterator_invalid "Invalid iterator."
Available in the experimental branch.

I think that is a perfectly viable solution.

Though, there has to be a way to manually check if the iterator is valid so the exception can be avoided in the script if it is prepared for it. Perhaps with an additional method "bool valid() const"?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Implemented


bool iterator::IsValid()

and fixed some bugs.

Name is ofcourse configurable.

Awesome! Thank you so much!
This literally saved me a lot of work. I was working on my own map implementation a while back, until Andreas pointed me here.
You nicely unified the code behind all containers, which really is a big plus.

The iterator additions make this complete. I love it.

I do prefer the standard bindings, so I'll change them like you suggested.
The extra safety measure will really come in handy as well. I can compile my engine with the security in debug, and without in release if it becomes relevant to increase performance after testing the game logic in debug. Perfect.

Thanks again

http://www.piko3d.net
Advertisement

Hi again!

I don't know if this is a question regarding Angelscript or AATC,

But there seems to be a minor error in how some AATC syntax is being parsed.

(Or maybe I'm missing something ;))

Please consider the following:


	map<Object@, Object@> myMap;
	if (@myMap[@key] == null)
		//Found an empty handle

Now this will work, but it gives me this warning:


The operand is implicitly converted to handle in order to compare them at row: X col: Y

this if for the line with the null comparison.

As I understand it, the @ sign in front of myMap in that instance, should make it clear that I already want to compare handles...

If I change the code to this:


    map<Object@, Object@> myMap;
    Object@ obj = myMap[@key];
    if (@obj == null)
	//Found an empty handle

The warning is gone, and everything still works as expected.

I'm using the AATC master as it is on GitHub and Angelscript Version 2.29.1
Is this a parse error? Binding problem ? Or am I doing something wrong?

Thanks again for this great Addon btw ;)

http://www.piko3d.net

This looks like it might be a problem in the script compiler. Most likely it hasn't got anything to do with Sami's template add-on library.

Though comparing handles as you do is OK, it is recommended that you use the identity operator instead. I.e.

map<Object@, Object@> myMap;
    if (myMap[@key] is null)
        //Found an empty handle

Using is or !is will avoid potentially difficult to find bugs should you forget to prefix the operand with @.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

By the way friends, I have recently made a refactoring of the library that puts everything inside namespaces and adds a convenient interface to create and manipulate AATC containers in c++. Before this using the containers in c++ was outrageously inconvenient due to too many c++ templates getting in the way. Now you can conveniently pass containers between c++ and angelscript and make use of them in c++ without 400 templates getting in your way.
The refactor was born of this github issue.
There's a bit of documentation available in the last post of the issue too.
The c++ side now makes use of metaprogramming techniques such as tag dispatch instead of std::conditional to achieve c++ side convenience. This makes it easier for AATC to support additional container types and somewhat reduces template smell.
The config file looks quite different because most options are now proper variables (not macros) and neatly organized inside namespaces. Some macros still remain.
I haven't merged the refactor to the master branch yet because it is quite the breaking change due to the new namespaces breaking literally all old names (in c++, not angelscript).
I have tested the refactor with ye olde AATC tests and my game project. Seems to work good with only minor name changes.
The angelscript side interface has no major changes. Some default method names have been consolidated a bit (insert_position_before -> just insert, erase_position_range & erase_position -> just erase) etc. They can be changed right back in the config if you like the long names or have a grudge against function overloading.
The refactor is available in its own github branch for now. Before merging to main / creating full documentation I would like some reviews from users / Andreas.
Does it work with your projects?
Did I manage to remove some feature you were using?
Is the c++ code more comprehensible?

Thanks for the response guys!

Andreas: Thanks that looks a lot cleaner too! I'll make sure to tell our script-guys to use that instead ;-)

Sami:

That's awesome. We don't use any containers in our interface as of yet. No need for it still, but I can think of some cases where it might come in handy.

Either way, I'll see if I can update to the refactor branch, so we can test it out.

Loving the aatc_config.hpp file ;)

http://www.piko3d.net

This topic is closed to new replies.

Advertisement