Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


kunajk

Member Since 23 Feb 2013
Offline Last Active Nov 05 2013 04:50 AM

Posts I've Made

In Topic: asOBJ_REF and asOBJ_VALUE at the same time

24 February 2013 - 06:11 PM

Hi, thanks for help :)

 

I don't make any comparison, becouse this is my only implementation. I am beginner with angelscript, so I dont do a rocket science :) I used shared refPointer becouse i dont want to copy string when I use operator=. Honestly I am afraid, that my implementation will be slower than ordinary std::string. 

void RefString::release() const 
{
	// Decrease ref count and delete if it reaches 0
	if( --(*refCount) == 0 )
	{
		for(size_t i=0; i<clones->size(); i++)
		{
			if((*clones)[i] == this) continue;
			delete (*clones)[i];
		}

		delete this->refCount;
		delete this->pString;
		delete this->clones;

		delete this;
	}
}


RefString& RefString::operator=(const RefString& str)
{
	if(this->pString == str.pString) return *this;

	std::vector<RefString*> thisClonesCopy = *(this->clones);
	std::vector<RefString*> strClonesCopy = *(str.clones);

	sort(strClonesCopy.begin(), strClonesCopy.end());
	sort(thisClonesCopy.begin(), thisClonesCopy.end());
	this->clones->resize(strClonesCopy.size() + thisClonesCopy.size());

	std::vector<RefString*>::iterator it = set_union(strClonesCopy.begin(), strClonesCopy.end(), thisClonesCopy.begin(), thisClonesCopy.end(), this->clones->begin());
	this->clones->resize(it - this->clones->begin());

	*(str.refCount) += *(this->refCount);

	if(this->pString) delete this->pString;
	if(this->refCount) delete this->refCount;
	if(str.clones) delete str.clones;

	for(size_t i=0; i<clones->size(); i++)
	{
		(*clones)[i]->pString = str.pString;
		(*clones)[i]->clones = this->clones;
		(*clones)[i]->refCount = str.refCount;
	}

	return *this;
}

 

Best regards


In Topic: asOBJ_REF and asOBJ_VALUE at the same time

23 February 2013 - 06:52 PM

Thanks for reply. Im new in angelscript but I like it. I write a ref string class and it works for my test scripts. Coudl you take a look if all is correct? 

 

#pragma once
#include <string>

class asIScriptEngine;

class RefString
{
	friend RefString& operator+(const RefString& str1, const RefString& str2);
	friend bool operator==(const RefString& lhs, const RefString& rhs);
	friend RefString* StringFactory(RefString& refString);
	friend void RegisterRefString(asIScriptEngine *engine);

	mutable int* refCount;
	std::string* pString;
	static asIScriptEngine* mEngine;
public:
	RefString();
	RefString(unsigned int byteLength, const char *s);
	RefString(const std::string& str);
	~RefString();

	void setString(const std::string& str) { if(pString) *pString = str; else pString = new std::string(str); }
	std::string* getString() { return pString; }
	
	RefString& operator=(const RefString& str);

	void addRef() const;
	void release() const;

	static void RegisterRefString(asIScriptEngine *engine);
	static void RegisterStdStringUtils(asIScriptEngine *engine);
};

RefString& operator+(const RefString& str1, const RefString& str2);
bool operator==(const RefString& str1, const RefString& str2);

 

#include "RefString.h"
#include <assert.h>
#include <angelscript.h>
#include "..\StringUtils.h"

using namespace std;

asIScriptEngine* RefString::mEngine = NULL;

RefString::RefString()
{
	// Let the constructor initialize the reference counter to 1
	refCount = new int(1);
	pString = new std::string;
}

RefString::RefString(unsigned int byteLength, const char *s)
{
	// Let the constructor initialize the reference counter to 1
	refCount = new int(1);
	pString = new std::string(s, byteLength);
}

RefString::RefString(const std::string& str)
{
	refCount = new int(1);
	pString = new std::string(str);
}

RefString::~RefString()
{
	delete refCount;
	delete pString;
}

RefString* StringFactory()
{
	// The class constructor is initializing the reference counter to 1
	RefString* stringRefCounter = new RefString(); 
	return stringRefCounter;//->getString();
}

RefString* StringFactory(RefString& refString)
{
	(*refString.refCount)++;
	return &refString;
}

// Our string factory implementation
RefString* StringFactory(unsigned int byteLength, const char *s)
{
	RefString* stringRefCounter = new RefString(byteLength, s); 
	return stringRefCounter;//->getString();
}

void RefString::addRef() const
{
	// Increase the reference counter
	(*refCount)++;
}
void RefString::release() const 
{
	// Decrease ref count and delete if it reaches 0
		if( --(*refCount) == 0 )
		delete this;
}

bool operator==(const RefString& str1, const RefString& str2)
{
	return *(str1.pString) == *(str2.pString);
}

RefString& RefString::operator=(const RefString& str)
{
	if(*this == str) return *this;

	if(this->pString) delete this->pString;

	str.addRef();
	this->pString = str.pString;
	this->refCount = str.refCount;
	return *this;
}

RefString& operator+(const RefString& str1, const RefString& str2)
{
	return *(new RefString(*(str1.pString) + *(str2.pString))); 
}

void RefString::RegisterRefString(asIScriptEngine *engine)
{
	RefString::mEngine = engine;

	int r;
	// Register the string type
	r = engine->RegisterObjectType("string", sizeof(RefString), asOBJ_REF); assert( r >= 0 );
	// Registering the factory behaviour
	r = engine->RegisterObjectBehaviour("string", asBEHAVE_FACTORY, "string@ f()", asFUNCTIONPR(StringFactory, (), RefString*), asCALL_CDECL); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("string", asBEHAVE_FACTORY, "string@ f(string@)", asFUNCTIONPR(StringFactory, (RefString&), RefString*), asCALL_CDECL); assert( r >= 0 );
	// Registering the addref/release behaviours
	r = engine->RegisterObjectBehaviour("string", asBEHAVE_ADDREF,  "void f()", asMETHOD(RefString,addRef), asCALL_THISCALL); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("string", asBEHAVE_RELEASE, "void f()", asMETHOD(RefString,release), asCALL_THISCALL); assert( r >= 0 );

	// Registering the string factory
	r = engine->RegisterStringFactory("string@", asFUNCTIONPR(StringFactory, (unsigned int, const char*), RefString*), asCALL_CDECL); assert( r >= 0 );

	r = engine->RegisterObjectMethod("string", "string &opAssign(const string &in)", asMETHODPR(RefString, operator =, (const RefString&), RefString&), asCALL_THISCALL); assert( r >= 0 );
	r = engine->RegisterObjectMethod("string", "string@ opAdd(const string &in) const", asFUNCTIONPR(operator+, (const RefString&, const RefString&), RefString&), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
	r = engine->RegisterObjectMethod("string", "bool opEquals(const string &in) const", asFUNCTIONPR(operator==, (const RefString &, const RefString &), bool), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
}

void RefString::RegisterStdStringUtils(asIScriptEngine * engine)
{
	int r;
	r = engine->RegisterGlobalFunction("void removeHtmlTags(string@, const string& in)", asFUNCTION(StringUtils::removeHtmlTags), asCALL_CDECL); assert( r >= 0 );
	r = engine->RegisterGlobalFunction("void removeSections(string @, const string& in, const string& in, const string& in, bool)", asFUNCTION(StringUtils::removeSections), asCALL_CDECL); assert( r >= 0 );	
	r = engine->RegisterGlobalFunction("void removeWhiteCharsAtBeging(string@, const string& in)", asFUNCTION(StringUtils::removeWhiteCharsAtBeging), asCALL_CDECL); assert( r >= 0 );
	r = engine->RegisterGlobalFunction("void removeWhiteCharsAtEnding(string@, const string& in)", asFUNCTION(StringUtils::removeWhiteCharsAtEnding), asCALL_CDECL); assert( r >= 0 );
	r = engine->RegisterGlobalFunction("void removeMultipleEnters(string@, const string& in)", asFUNCTION(StringUtils::removeMultipleEnters), asCALL_CDECL); assert( r >= 0 );
}


 



void main()
{
	print("Hello world\n");
	print("AB" + "CD" + "\n");

	string sr1 = "raz";
	string sr2 = "dwa";
	string str3("dupa\n");
	print(sr1);
	print(sr2);
	print(str3);
	if(sr1 == sr2) print("rowne");
	else print("rozne");
}

In Topic: asOBJ_REF and asOBJ_VALUE at the same time

23 February 2013 - 10:51 AM

Thanks for answer. Its working, but I prefer '@' befour result param, to show, that this param to show that this param will be changed(programing style only). I understand, that I cant use only @ in ref type objects?

removeSections(@strToRet, str, "<--", "-->", true);

PARTNERS