Advertisement

Preserve variable state after function call

Started by May 30, 2007 02:42 PM
14 comments, last by _Sigma 17 years, 6 months ago
The complexity of find() depends on the container you're using it on. A plain std::map is usually implemented as a binary tree. I couldn't find any Big O for it, though.

An alternative would be to use a hash_map, which is usually implemented as a hash table, wich pretty much gives you O(1).

The choice depends on how many items are in the map and how fast your hash function is. The best way to determine this is to make two versions of the code in a simple test program and profile. I personally use AMD's CodeAnalyst (it's a free download, probably only works on AMD CPUs). If you need a string hash function, try this: http://www.burtleburtle.net/bob/hash/index.html#lookup
Quote: Original post by Deyja
Why standardize the function that returns the class name, when you could just standardize the class name? Or are script-defined classes available in other modules now? Or are you throwing all your scripts into one module?


To add a little flexibility to the script writer. By being able to name the class something relevant to what it does (FootSoldier, NinjaTurtle, Shredder, etc.). It was just a design decision.

Also, if the day ever comes where we can import classes from other modules, I want to be ready.
Advertisement
midnite:

I believe your design is pretty much how I myself imagine using AngelScript in a game engine. If you also use interfaces you may simplify the validation of making sure that the script implements the methods you need. Example:

// The interface is declared by the application in a separate script sectioninterface ScriptEntity{  void DoFrame();}// The user implemented class inherits from the interfaceclass TestClass : ScriptEntity{  TestClass()  {    m_counter = 0;  }  void DoFrame()  {    m_counter++;  }  int m_counter;}// We can use a factory function instead of returning the name ScriptEntity @CreateEntity(){  return TestClass();}


_Sigma:

find() is O(log n) for binary trees. For small trees the time spent in find() will be insignificant to the time spent executing the scripts.

However there are some very simple optimizations you can do, for example, when you create a new context you're inserting it in the map, and then doing a find to recover it again. Why not just store the pointer you inserted, that way you economize one find? Also, perhaps most of your function calls will finish immediately, so it might be worth it to only insert the context in the map if it needs to be stored until the next frame.

Also, why do you store the functions you wish to call by name? If you store the function id instead you only have to call GetFunctionIdByDecl() once per function. This function call is quite expensive, in that AngelScript has to parse the declaration and then compare against the functions available, so you definitely do not want to call this more than necessary.

Other than that your implementation looks ok. As you continue to develop your engine, you'll probably find ways to improve upon it even more. But as an outsider it's very difficult to give suggestions on more improvements since we cannot foresee the exact needs that you have.

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

Quote: Original post by WitchLord
midnite:

I believe your design is pretty much how I myself imagine using AngelScript in a game engine. If you also use interfaces you may simplify the validation of making sure that the script implements the methods you need. Example:

*** Source Snippet Removed ***



Yes, Interfaces are good if you require a certain number of guaranteed member functions. However, I went with the approach of making all the functions, called from C++, optional. This way if a script has nothing to do in a function it simply does not implement it - so it never gets called. When I build a module I check to see what member functions are implemented in the script class (by looking for specific declarations). For those that are found I store their function ID, for those that are not it's just -1.

This also goes into how I implemented a state machine in my code. Say the default state of a script uses the "void Default_DoFrame(float)" member function. The script can call a function like ChangeState("falling") and now, instead of C++ calling Default_DoFrame, it calls void falling_DoFrame(float) until it is told differently. There are a number of other things I'm doing too, but you can get the idea.
I understand. It sounds like a very good idea. Thanks for sharing it with us.

I have an item on my to-do list to investigate if I can aid this state changing pattern in AngelScript in someway, though for the moment what you're doing sounds like the best way. Let me know if you can think of anything that would make your implementation simpler.

Regards,
Andreas

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

Quote: Also, why do you store the functions you wish to call by name? If you store the function id instead you only have to call GetFunctionIdByDecl() once per function. This function call is quite expensive, in that AngelScript has to parse the declaration and then compare against the functions available, so you definitely do not want to call this more than necessary.
Unless I've missed something, I only call the GetFunctionIdByDecl() once, which is the first time the function is called, other wise, it just gets it from the IDMap.

Quote:
However there are some very simple optimizations you can do, for example, when you create a new context you're inserting it in the map, and then doing a find to recover it again. Why not just store the pointer you inserted, that way you economize one find? Also, perhaps most of your function calls will finish immediately, so it might be worth it to only insert the context in the map if it needs to be stored until the next frame.
The first one I should have already done. I like the last one! Thanks!

This topic is closed to new replies.

Advertisement