• Advertisement
Sign in to follow this  

to free or not to free...

This topic is 4347 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i'm wondering how i can reach something like this in angelscript.. say i've got something like an iterator logic like this (in c++): Container container("..."); Node* node = container.getFirstNode(); while(node != 0) { node->doSomethingSilly(); node = node->getAdjacentNode(); } how can i register a Node class to be a pointer and not a static property (which may be initialized by a 0 pointer, if getAdjacentNode returns 0, which is impossible) ? i have thought about using a wrapper class like this (c++): class asNode { public: asNode(const asNode&); // to let the script allocate a node asNode(asNode*); // which not allocate a node but holds the pointer ~asNode(); // this is the wacky part asNode* getAdjacentNode(); // i have to create a new asNode ? Node* node; } but still i don't get the point, because you can build a Node in the script to be used (which allocates memory by new Node*), and also you can get a pointer that u don't have to free. so in the destructor i don't know if i have to deallocate the object or not... maybe i can use a bool holdObject in the wrapper class to know if i have to deallocate or not the Node*. can i achieve something like this with the usage of handles ? ciao

Share this post


Link to post
Share on other sites
Advertisement
To do this with AngelScript you need to register an object type with the behaviours asBEHAVE_ADDREF and asBEHAVE_RELEASE so that object handles are supported. This will allow you to write a script like this:


Container container("...");
Node @node = container.getFirstNode();
while( node != null )
{
node.doSomethingSilly();

node = node.getAdjacentNode();
}


Unless your node class in C++ already uses reference counting for memory management you'll have to write a wrapper class to do the proper management.

Such a wrapper class might look something like this (pretty much a smart pointer):


class NodeWrapper
{
public:
NodeWrapper() {node = 0; refCount = 1;}
NodeWrapper(Node *_node) {node = _node; refCount = 1;}

void AddRef() {refCount++;}
void Release() {if( --refCount == 0 ) delete this;}

NodeWrapper &operator=(const NodeWrapper &other) {node = other.node;}

void doSomethingSilly() {node->doSomethingSilly();}
NodeWrapper *getAdjacentNode() {Node *next = node->getAdjacentNode(); if(next) return new NodeWrapper(next); else return 0;}

protected:
~NodeWrapper() {/* Do I delete the node here? What if another NodeWrapper is holding the same node? */}

Node *node;
int refCount;
};

Share this post


Link to post
Share on other sites
okay man, thanx a lot. now i got it, i think...
the only thing that i don't understand is actually how to do both handles and creation of the object in the script, without managing also the pointer ownership as i want be able to do:

// both

Container container("...");
Node @node = container.getFirstNode();
while( node != null )
{
node.doSomethingSilly();
node = node.getAdjacentNode();
}

// and

Node node(x,y);
n.doSomethingSilly();
container.push (node);

in the second case i've newed the Node pointer,
so i need to free this.

Share this post


Link to post
Share on other sites
You definitely have a difficult problem to solve. The easiest way to solve it is to have the Node class itself use reference counting. However I assume you cannot change the Node class, or you probably wouldn't have these doubts.

Unfortunately I cannot think of any way to solve this in a safe way (other than changing the Node class), i.e. in a way that it will always work automatically.

If you can give the responsibility to the script writer to do the proper memory management of the Node class, then it is easier to solve the interface between AngelScript and your application. If you can allow that, then you could simply register the Node* as a special type, and have functions to allocate and deallocate the Node appropriately. This would of however open up your script to vulnerabilities which may lead to memory leaks or application crashes.

Share this post


Link to post
Share on other sites
yeah i cannot change the node class, and must leave as it is. if i could change, i do for sure... anyway i've thought about adding a ownerShip variable which is initialized to 1 if the asNode is creating a new Node, or to 0 if the object is passed as pointer from another function. in this case i can easily determine, after reference counting, if i have to delete the Node pointer or not, but what i do if someone from the script do assign nodes in mixed ownership ? aaaaargh... wacky problem, indeed, not that difficult but actually i'm just too tired for thinking a good approach.
anyway thanx man for clarify me.
just a question, when pointers in script will be introduced ?

Share this post


Link to post
Share on other sites
Re-introducing pointers in AngelScript has a quite low priority for me right now, so I can't say when I'll get around to it.

However, you don't have to wait until pointers are available to solve the problem. You could just do what I said in my last post. Example:


engine->RegisterObjectType("NodePtr", sizeof(Node*), asOBJ_PRIMITIVE);
engine->RegisterObjectMethod("NodePtr", "void doSomethingSilly()", asFUNCTION(doSomethingSilly), asCALL_CDECL_OBJLAST);
... // More functions and methods

=-=-=
void doSomethingSilly(Node **pp)
{
(*p)->doSomethingSilly();
}


The script will be a bit different, but not by much.


Container container("...");
NodePtr node = container.getFirstNode();
while( isNull(node) )
{
node.doSomethingSilly();
node = node.getAdjacentNode();
}

NodePtr node = CreateNode(x,y);
n.doSomethingSilly();
container.push(node);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement