• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

Wracky

Members
  • Content count

    36
  • Joined

  • Last visited

Community Reputation

171 Neutral

About Wracky

  • Rank
    Member
  1. Ah! Thanks! I see what you mean. Even when looking for it, it took me a little while to see that the opPreInc and opPostInc functions returned a bool. Our scripters missed it too ;) In C++, the convention for these operators is usually to return a reference to the object itself, or a copy (for postInc). This is convenient in some cases, for instance when pasing them as arguments. I really like that you thought about minimizing AS function calls in the for loop though, so I would definitely appreciate a method for this, so that the current behaviour can still be used. Good thinking! I've tested out the solution you proposed for our String handling, and it works great. Thank you. During testing, I did come accross another small bug, regarding opCmp. The angelscript manual states the following:     So for the less operator, the function returns a negative value. Not necessarily -1. I found AATC just checks for -1. For performance reasons, (and to follow the example of strcmp, our String is implemented to return the numerical difference between the first mismatching characters which will often be smaller than -1. I managed to fix it by changing line 232 in aatc_container_shared.cpp as follows: result = (cc->GetReturnDWord() == -1); //Should be.. result = ((int)cc->GetReturnDWord() < 0); opCmp is expected to return an int, so this sould be fine. With that said, it seems like everything is in order now. I can use Strings directly, or use String@, so the scripter can decide for them selfs if they want to copy string or not ;-) As for the Hash function, sure, I would gladly specify one manually. Thanks again for your reply, and keep up the good work!  
  2. Ah right. Makes sense! In other news, I think I've found a curious bug in AATC: Let's say I want to replicate the following C++ code in Angelscript AATC: std::map<int, int> myMap; myMap[0] = 1; std::cout << "myMap has: " << myMap.size() << " elements" << std::endl; for (auto& iter = myMap.begin(); iter != myMap.end(); ++iter) { std::cout << "Key: " << iter->first << " Value: " << iter->second << std::endl; } return 0; //This will output the following (stating the obvious) myMap has: 1 elements Key: 0 Value: 1 We've translated this to: ("echo" is a simple function we've bound that does console output) map<int, int> myMap; myMap[0] = 1; echo("myMap has " + String(myMap.size()) + " elements"); for (auto iter = myMap.begin(); iter != myMap.end(); ++iter) { echo ("Key: "+ String(iter.key) + " Value: " + String(iter.value)); } //This will output the following: myMap has 1 elements Key: 0 Value: 1 Key: 0 Value: 1 While the C++ program will output exactly one item, the angelscript version will output 2 values! Even though myMap.size() returns 1. It seems like there's a problem with the iterators somehow. They don't behave like their C++ counterparts.   While testing, I noticed something else with the following Map<int, String@> myMap; @myMap[0] = "Foo"; In this case, my String's = operator get's called, which in my opinion shouldn't happen ? It crashes, as the handle being assigned to is a nullptr. I was expecting it to just reassign handles. Is that possible? I loved the DEFAULT_HANDLEMODE_DIRECTCOMP option in the config, I hoped this would work in a similar fashion. Thanks for reading, Let me know what you think!    Regards, Wracky
  3. Thanks!! Ok that's just silly :D I've updated my version to the patch, and it seems to work. I did notice something else though. We do Strings a bit differently in our engine. They are ref objects, and all our classes are registered with a name starting with a Capital. So I always spend some time converting some of the types, before I can start using AATC. While doing that, I came across the script_Funcpointer class, which needs a String to specify the script function to call.   I've solved a lot of callback situations with funcdefs, which work great when the type is known. Everything you need is basically in the asIScriptFunction class, but the trick is to get Angelscript to pass one to you :D A funcdef for less<T>( const T& a, T& b) would be awesome, but I don't think that is currently possible, is it?  Anyway, thanks again. loving aatc as well ;)
  4. Hi Andreas, Thanks for the reply. Yeah I'm afraid so. Too bad though. It's nice that Angelscript is still available on so many different compilers/versions, and a bit of a bummer when such a nice add-on as this one requires a specific compiler.    We will eventually update to Visual Studio 2015, but I'm currently not in the mood of recompiling all our other dependencies ;-)   For now I've decided to revert AATC to an older version from my own repository. I don't know which version it is, but I just changed all the references to asIObjectTypeInfo and related functions to asITypeInfo, and now it works fine.   Shame though.. of course I'd like to keep AATC up to date as well. Anyway, I have a solution for now.    Thanks for keeping Angelscript alive. It's an amazing product :-)
  5. So I've just updated my Angelscript again, and noticed my version of AATC didn't use TypeInfo yet. So I decided to update AATC as well, but I have troubles getting it to compile. I don't know if this is a fault in my project, or not, but I'm getting a lot of errors like this: 1> aatc_container_shared.cpp 1>..aatc\aatc_container_shared.hpp(358): error C2988: unrecognizable template declaration/definition (..\..\src\Scripting\AngelScript\aatc\aatc.cpp) 1>..aatc\aatc_container_shared.hpp(358): error C2988: unrecognizable template declaration/definition (..\..\src\Scripting\AngelScript\aatc\aatc_container_set.cpp) 1>..aatc\aatc_container_shared.hpp(358): error C2059: syntax error : '<L_TEMPLATEDECL>' (..\..\src\Scripting\AngelScript\aatc\aatc.cpp) 1>..aatc\aatc_container_shared.hpp(358): error C2059: syntax error : '<L_TEMPLATEDECL>' (..\..\src\Scripting\AngelScript\aatc\aatc_container_set.cpp) 1>..aatc\aatc_container_shared.hpp(359): error C2059: syntax error : '}' (..\..\src\Scripting\AngelScript\aatc\aatc.cpp) 1>..aatc\aatc_container_shared.hpp(358): error C2988: unrecognizable template declaration/definition (..\..\src\Scripting\AngelScript\aatc\aatc_container_list.cpp) 1>..aatc\aatc_container_shared.hpp(359): error C2059: syntax error : '}' (..\..\src\Scripting\AngelScript\aatc\aatc_container_set.cpp) 1>..aatc\aatc_container_shared.hpp(341): error C2888: 'void register_all_tempspec_basics_for_container(asIScriptEngine *)' : symbol cannot be defined within namespace 'autoregister' (..\..\src\Scripting\AngelScript\aatc\aatc.cpp) 1>..aatc\aatc_container_shared.hpp(358): error C2059: syntax error : '<L_TEMPLATEDECL>' (..\..\src\Scripting\AngelScript\aatc\aatc_container_list.cpp) 1>..aatc\aatc_container_shared.hpp(341): error C2888: 'void register_all_tempspec_basics_for_container(asIScriptEngine *)' : symbol cannot be defined within namespace 'autoregister' (..\..\src\Scripting\AngelScript\aatc\aatc_container_set.cpp) 1>..aatc\aatc_container_shared.hpp(359): error C2059: syntax error : '}' (..\..\src\Scripting\AngelScript\aatc\aatc_container_list.cpp) 1>..aatc\aatc_container_shared.hpp(341): error C2888: 'void register_all_tempspec_basics_for_container(asIScriptEngine *)' : symbol cannot be defined within namespace 'autoregister' (..\..\src\Scripting\AngelScript\aatc\aatc_container_list.cpp) 1>..aatc\aatc_container_shared.hpp(358): error C2988: unrecognizable template declaration/definition (..\..\src\Scripting\AngelScript\aatc\aatc_common.cpp) 1>..aatc\aatc_container_shared.hpp(358): error C2059: syntax error : '<L_TEMPLATEDECL>' (..\..\src\Scripting\AngelScript\aatc\aatc_common.cpp) 1>..aatc\aatc_container_shared.hpp(359): error C2059: syntax error : '}' (..\..\src\Scripting\AngelScript\aatc\aatc_common.cpp) 1>..aatc\aatc_container_shared.hpp(341): error C2888: 'void register_all_tempspec_basics_for_container(asIScriptEngine *)' : symbol cannot be defined within namespace 'autoregister' (..\..\src\Scripting\AngelScript\aatc\aatc_common.cpp) 1> aatc_container_unordered_map.cpp I'm using Visual Studio 2013, and have used the current master branch for AATC. Am I doing something wrong? :) Thanks!
  6. 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 ;) 
  7. 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 ;)  
  8. 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
  9. Sweet! I'm downloading it now. Thank you so much for the quick response. I found Andreas' suggestion interesting as well. Is it possible to make the map behave more like the stl one ? Can it be extended so that find returns an iterator directly?   If that is possible, maybe functions like begin, end, rbegin, rend etc can also be supported. In that case, find can return end if an object cannot be found, like stl does. Thanks again.
  10. Hi Sami, Thanks for posting! Looks good! Do you have any plans for adding support for opIndex to the map and unorderd_map ? So that maps can be used like myMap[myKey] = myValue ? I think that would be a nice addition.   Another thing:  While trying to add AACT to our project, I noticed that it didn't play nice with our custom String class. Sure there is a define in the aatc_config that I can change, but our string doesn't have the same interface as the std::string and this gives some problems in the implementation of the aatc_script_Funcpointer::Set functions.   It was easily to fixed though, and kind of our problem for being boneheads and writing our own string class :P I see why that's kind of a problem when you can't use asIScriptFunction* instead of names.... Anyway! Keep up the good work!
  11. Thanks for the quick responses. I got it to work now :) with the type ID from the scriptModule. The CScriptWeakRef also assumes it gets an handle that was reffed when it was passed, so it releases it as to not keep the strong. So to make sure the object didn't get destroyed because of that I had to pass the object reffed (so add another ref)   Anywayz, glad to finally get it to work. Oh btw, I looked at the documentation regarding asBEHAVE_GET_WEAKREF_FLAG, and it looked like a whole lot to take in. Our application though, is fully aware of refcounting on application-registered objects, whether they were reffed/created by script or by the application. We have our own set of smart pointers, much like the ones in boost, that count strong as well as weak references. Ref-objects expose addRef and Release functions that share the same use/ref count, which we use for the behaviours in script.   So basically I could write my own template specialization for weakref<T> instead of adding the WEAKREF_FLAG behavior I guess? If I use template specialization for all Application types, and use CScriptWeakRef for everything else, I don't have to deal with the shared boolean, and can use our existing weakref methods.  I'll try that later :) Well thanks again! Regards, Wracky.  
  12. I tried the GetTypeIdByDecl() approach before I commented, but that just returns asINVALID_TYPE for anything other than Application classes. The function is invoked by script, so it is compiled and other types should be available at the point of the call.   Thanks for telling me about the asBEHAVE_GET_WEAKREF_FLAG. Can't believe I've missed that :-) Regards, Wracky
  13. Hi Andreas,  Thank you for your tips. Sorry for my late response. I was on holiday for a bit :)   The example you gave me still doesn't work. The main problem being that GetObjectTypeByDecl doesn't exist :) I tried to make it work with GetObjectTypeByName, but that function just returns NULL unless I ask for a Class name registered by the application. So on both "weakref<Foo>" and "Foo" it just returns NULL. "Control" for instance, does work.   I did some hacking right before I went, and managed to get it to work in a (probably) ugly way, by just skipping the ReleaseScriptObject calls, and passing Type in cases where getSubType returned NULL. (when I still constructed the weakref with objectype instead of weakref<Foo> type. This seemed to work but I had no idea if I broke anything else.   So far it's obvious to me that the weakref was written with script binding in mind ;-) What I was wondering about though, is since there is no interface that communicates the refcount of objects of application registered types, weakrefs in script will probably be set to null while the application still holds refs, meaning the weakref will become null while the object is not destroyed. Is this assumption correct ? It would really be wonderful in angelscript could support weakrefs better. callbacks could default to no-op when objects decay so they no longer ref the object they are holding. addRef/release functions could return the refcount so the scriptengine would be aware of the objects refcount, even when the object comes from the application.   Anyway, I could probably throw something together based on the weakref implementation that would work, but ofcourse it would be nice to have something that is also supported in future releases :)   What do you recommend?   Regards,   Wracky  
  14. Hi Andreas, So I finally got around to implementing this, and I noticed a problem with the CScriptWeakRef. The code you showed me for weakreffing the object in the engine throws an exception when I pass it a script object. void FuncReceivingDelegate(asIScriptFunction *delegate) { // Get the object pointer from the delegate if( delegate->GetFuncType() == asFUNC_DELEGATE ) { void *obj = delegate->GetDelegateObject(); asIObjectType *objType = delegate->GetDelegateObjectType(); asIScriptFunction *method = delegate->GetDelegateFunction(); // Create a weak ref to keep the pointer to the object CScriptWeakRef *weakRefToDelegatedObject = new CScriptWeakRef(obj, objType); // Store the weak ref and the method instead of the original delegate ... } delegate->Release(); } The constructor for the CScriptWeakRef throws an exception on this line:   // Release the handle that was received, since the weakref isn't suppose to prevent the object from being destroyed m_type->GetEngine()->ReleaseScriptObject(m_ref, m_type->GetSubType()); As far as I can see, GetSubType returns 0 if the object is not templated? So it passes 0 as subtype here, and crashes in "ReleaseScriptObject" upon trying to access this null-pointer.   I've tried passing m_type instead of subtype when subtype was null, but that messes up the ref-count and destroys my object when it is still in scope. adding another m_type->AddRef() didn't solve that. Since I don't know exactly what I'm doing, I thought I'd ask ;-)   Here's my script: Timer@ timer; class Foo { void bar() { echo ("Called bar...\n"); } ~Foo() { echo ("Foo destroyed\n"); } } Foo@ f; void main(Control@ control) { @f = Foo(); @timer = control.createTimer(1000, true); timer.elapsed += Action(f.bar); timer.start(); } Sincerely,   Wracky  
  15. OK, I've tried some more things, and then realized that what I was asking is probably something weird I thought about how other languages solve this problem, and I just realized that unregistering callbacks is always a bit awkward   I thought this could be handled with the lifespan of the function handle, but this is not usually the case in other languages. So I reckon this might not be the best way to go, and is perhaps not always what you want, as it requires the user to keep the thing alive/in scope some how.   You did help me a great deal in understanding what is going on, and have given me a couple of options to solve this. At least now I know how to let the App know when the delegate CANNOT be called (and the user forgot to unregister the callback). I particularly like the callback function option, as it eliminates inactive objects that stay there simply because the didn't get called.   The Object weakref is nice to make sure I don't take ownership of the object.    I think I will go with the C# way of deregistering callbacks, by passing the delegate once for register, and another time to unregister it. So perhaps something like: timer.register(timerCallback(myObject.myFunction)); timer.unregister(timerCallback(myObject.myFunction)); //Or perhaps I can even go full C# and make this work :) timer.event += timerCallback(myObject.myFunction); timer.event -= timerCallback(myObject.myFunction); I noticed that when a function handle is passed it is the same, even when stored in different handle instances, and the delegates are not, but I can use GetDelegateFunction in that case. I'll use the function pointers to identify which callback to remove, and use the userdata callback to clean up callbacks that are no longer valid. Thank you very much for the information, and taking the time of helping me with this. Regards, Wracky.