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");
}