MemberInfo *Type::findMember(const char *name, bool includeBases) { if (cached) { MemberInfo **minfo = memberCache.get(name); if (minfo) { return *minfo; } return NULL; } for (UTsize i = 0; i < members.size(); i++) { MemberInfo *m = members.at(i); if (!strcmp(m->getName(), name)) { return m; } } if (includeBases && baseType) { MemberInfo *m = baseType->findMember(name, true); return m; } return NULL; }
void Assembly::bootstrap() { utArray<Type *> types; getTypes(types); Type *btype = vm->getType("system.Bootstrap"); for (UTsize i = 0; i < types.size(); i++) { Type *type = types[i]; if (type->getFullName() == "system.Null") { continue; } if (type->castToType(btype)) { MemberInfo *mi = type->findMember("initialize"); assert(mi); assert(mi->isMethod()); MethodInfo *method = (MethodInfo *)mi; method->invoke(NULL, 0); } } }
void NativeTypeBase::validate(Type *type) { utArray<MemberInfo *> members; MemberTypes mtypes; mtypes.property = true; mtypes.field = true; mtypes.constructor = true; mtypes.method = true; type->findMembers(mtypes, members); lua_State *L = type->getAssembly()->getLuaState()->VM(); for (UTsize i = 0; i < members.size(); i++) { MemberInfo *info = members.at(i); // if we don't have an ordinal we aren't native if (!info->isNative()) { continue; } checkBridge(info); } }
void ReplSet::startHealthThreads() { MemberInfo* m = _members.head(); while( m ) { FeedbackThread *f = new FeedbackThread(); f->m = m; m = m->next(); } }
FieldInfo *Type::findFieldInfoByName(const char *name) { MemberInfo *mi = findMember(name); if (mi && mi->isField()) { return (FieldInfo *)mi; } return NULL; }
MethodInfo *Type::getMethodInfo(const utString& name) { MemberInfo *minfo = findMember(name.c_str()); if (minfo && minfo->isMethod()) { return (MethodInfo *)minfo; } return NULL; }
PropertyInfo *Type::findPropertyInfoByName(const char *name) { MemberInfo *mi = findMember(name); if (mi && mi->isProperty()) { return (PropertyInfo *)mi; } return NULL; }
void Type::findMembers(const MemberTypes& memberTypes, utArray<MemberInfo *>& membersOut, bool includeBases, bool includePropertyGetterSetters) { if (!includeBases) { membersOut.clear(); } for (size_t i = 0; i < members.size(); i++) { MemberInfo *m = members.at((int)i); if (m->isConstructor() && memberTypes.constructor) { membersOut.push_back(m); } if (m->isMethod() && memberTypes.method) { membersOut.push_back(m); } if (m->isField() && memberTypes.field) { membersOut.push_back(m); } if (m->isProperty() && memberTypes.property) { membersOut.push_back(m); if (includePropertyGetterSetters) { PropertyInfo *p = (PropertyInfo *)m; if (p->getter && (p->getter->getDeclaringType() == p->getDeclaringType())) { membersOut.push_back(p->getter); } if (p->setter && (p->setter->getDeclaringType() == p->getDeclaringType())) { membersOut.push_back(p->setter); } } } } if (baseType && includeBases) { baseType->findMembers(memberTypes, membersOut, true, includePropertyGetterSetters); } }
ConstructorInfo *Type::getConstructor() { for (UTsize i = 0; i < members.size(); i++) { MemberInfo *m = members.at(i); if (m->isConstructor()) { return (ConstructorInfo *)m; } } return NULL; }
void Type::cache() { if (baseType) { baseType->cache(); } if (cached) { return; } cached = true; MemberTypes types; types.constructor = true; types.field = true; types.method = true; types.property = true; utArray<MemberInfo *> allMembers; findMembers(types, allMembers, true, true); maxMemberOrdinal = 0; for (UTsize i = 0; i < allMembers.size(); i++) { MemberInfo *mi = allMembers.at(i); if (mi->ordinal > maxMemberOrdinal) { maxMemberOrdinal = mi->ordinal; } } maxMemberOrdinal++; memberInfoOrdinalLookup = (MemberInfo **)lmAlloc(NULL, sizeof(MemberInfo *) * maxMemberOrdinal); memset(memberInfoOrdinalLookup, 0, sizeof(MemberInfo *) * maxMemberOrdinal); for (int i = (int)(allMembers.size() - 1); i >= 0; i--) { MemberInfo *mi = allMembers.at(i); memberCache.insert(mi->getName(), mi); memberInfoOrdinalLookup[mi->getOrdinal()] = mi; } }
bool Type::isNativeMemberPure(bool ignoreStaticMembers) { //if (!attr.isNative) // return false; for (UTsize i = 0; i < members.size(); i++) { MemberInfo *memberInfo = members.at(i); if (ignoreStaticMembers && memberInfo->isStatic()) { continue; } if (memberInfo->isConstructor()) { ConstructorInfo *cinfo = (ConstructorInfo *)memberInfo; if (cinfo->defaultConstructor) { continue; } } if (memberInfo->isConstructor() || memberInfo->isMethod()) { if (!((MethodBase *)memberInfo)->isNative()) { return false; } } if (memberInfo->isProperty()) { PropertyInfo *pinfo = (PropertyInfo *)memberInfo; if (pinfo->getGetMethod() && !pinfo->getGetMethod()->isNative()) { return false; } if (pinfo->getSetMethod() && !pinfo->getSetMethod()->isNative()) { return false; } } if (memberInfo->isField()) { if (!memberInfo->getOrdinal()) { return false; } } } if (baseType) { return baseType->isNativeMemberPure(); } return true; }
MethodInfo *Type::findOperatorMethod(const utString& methodName) { MemberInfo *mi = findMember(methodName.c_str()); if (!mi) { return NULL; } if (!mi->isMethod()) { return NULL; } if (!((MethodInfo *)mi)->isOperator()) { return NULL; } return (MethodInfo *)mi; }
void LSLuaState::invokeStaticMethod(const utString& typePath, const char *methodName, int numParameters) { Type *type = getType(typePath.c_str()); lmAssert(type, "LSLuaState::invokeStaticMethod unknown type: %s", typePath.c_str()); MemberInfo *member = type->findMember(methodName); lmAssert(member, "LSLuaState::invokeStaticMethod unknown member: %s:%s", typePath.c_str(), methodName); if (!member->isMethod()) { lmAssert(0, "LSLuaState::invokeStaticMethod member: %s:%s is not a method", typePath.c_str(), methodName); } MethodInfo *method = (MethodInfo *)member; lmAssert(method->isStatic(), "LSLuaState::invokeStaticMethod member: %s:%s is not a static method", typePath.c_str(), methodName); method->invoke(NULL, numParameters); }
void cGuild::save() { QStringList fields; fields.append( QString::number( serial_ ) ); fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( name_ ) ) ); fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( abbreviation_ ) ) ); fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( charta_ ) ) ); fields.append( QString( "'%1'" ).arg( PersistentBroker::instance()->quoteString( website_ ) ) ); fields.append( QString::number( alignment_ ) ); if ( leader_ ) { fields.append( QString::number( leader_->serial() ) ); } else { fields.append( "-1" ); } fields.append( QString::number( founded_.toTime_t() ) ); if ( guildstone_ ) { fields.append( QString::number( guildstone_->serial() ) ); } else { fields.append( "-1" ); } PersistentBroker::instance()->executeQuery( QString( "INSERT INTO guilds VALUES(%1);" ).arg( fields.join( "," ) ) ); // Save Members/Canidates P_PLAYER player; foreach ( player, members_ ) { MemberInfo* info = getMemberInfo( player ); PersistentBroker::instance()->executeQuery( QString( "INSERT INTO guilds_members VALUES(%1,%2,%3,'%4',%5);" ) .arg( serial_ ).arg( player->serial() ).arg( info->showSign() ? 1 : 0 ) .arg( PersistentBroker::instance()->quoteString( info->guildTitle() ) ) .arg( info->joined() ) ); }
// TODO: Unify this with the JIT bc generator binary expressions // https://theengineco.atlassian.net/browse/LOOM-640 // https://theengineco.atlassian.net/browse/LOOM-641 Expression *TypeCompiler::visit(BinaryOperatorExpression *expression) { Tokens *tok = Tokens::getSingletonPtr(); Expression *eleft = expression->leftExpression; Expression *eright = expression->rightExpression; // operator overloads lmAssert(eleft->type && eright->type, "Untyped binary expression"); const char *opmethod = tok->getOperatorMethodName(expression->op); if (opmethod) { MemberInfo *mi = eleft->type->findMember(opmethod); if (mi) { lmAssert(mi->isMethod(), "Non-method operator"); MethodInfo *method = (MethodInfo *)mi; lmAssert(method->isOperator(), "Non-operator method"); utArray<Expression *> args; args.push_back(eleft); args.push_back(eright); ExpDesc opcall; ExpDesc emethod; BC::singleVar(cs, &opcall, eleft->type->getName()); BC::expString(cs, &emethod, method->getName()); BC::expToNextReg(cs->fs, &opcall); BC::expToNextReg(cs->fs, &emethod); BC::expToVal(cs->fs, &emethod); BC::indexed(cs->fs, &opcall, &emethod); generateCall(&opcall, &args, method); expression->e = opcall; return expression; } } // dynamic cast if ((expression->op == &tok->KEYWORD_IS) || (expression->op == &tok->KEYWORD_INSTANCEOF) || (expression->op == &tok->KEYWORD_AS)) { lmAssert(eleft->type && eright->type, "Untype expression"); FuncState *fs = cs->fs; ExpDesc object; BC::singleVar(cs, &object, "Object"); ExpDesc method; if (expression->op == &tok->KEYWORD_IS) { BC::expString(cs, &method, "_is"); } else if (expression->op == &tok->KEYWORD_AS) { BC::expString(cs, &method, "_as"); } else { BC::expString(cs, &method, "_instanceof"); } BC::expToNextReg(fs, &object); BC::expToNextReg(fs, &method); BC::expToVal(fs, &method); BC::indexed(fs, &object, &method); utArray<Expression *> args; args.push_back(eleft); args.push_back(new StringLiteral(eright->type->getAssembly()->getName().c_str())); args.push_back(new NumberLiteral(eright->type->getTypeID())); generateCall(&object, &args); expression->e = object; return expression; } BinOpr op = getbinopr(expression->op); if (op == OPR_LOOM_ADD) { lmAssert(eleft->type && eright->type, "Untyped add operaton %i", lineNumber); int ncheck = 0; if (eleft->type->isEnum() || (eleft->type->getFullName() == "system.Number")) { ncheck++; } if (eright->type->isEnum() || (eright->type->getFullName() == "system.Number")) { ncheck++; } if (ncheck != 2) { op = OPR_CONCAT; } } // If we're concat'ing arbitrary types with a string, we need to coerce them // to strings with Object._toString otherwise the Lua VM will error when // it can't concat (which has strict rules, for instance cannot concat nil) if ((op == OPR_CONCAT) && ((eleft->type->getFullName() == "system.String") || (eright->type->getFullName() == "system.String"))) { // coerce left to string, must be done even for string types as they may be null coerceToString(eleft); BC::infix(cs->fs, op, &eleft->e); // coerce right to string, must be done even for string types as they may be null coerceToString(eright); // and the binary op BC::posFix(cs->fs, op, &eleft->e, &eright->e); // save off expression and return expression->e = eleft->e; return expression; } eleft->visitExpression(this); BC::infix(cs->fs, op, &eleft->e); eright->visitExpression(this); BC::posFix(cs->fs, op, &eleft->e, &eright->e); expression->e = eleft->e; // promote to register BC::expToNextReg(cs->fs, &expression->e); return expression; }
void Type::assignOrdinals() { if (baseType) { baseType->assignOrdinals(); } // already assigned? if (members.size() && members.at(0)->ordinal) { return; } MemberTypes types; types.constructor = true; types.field = true; types.method = true; types.property = true; utArray<MemberInfo *> allMembers; findMembers(types, allMembers, true, true); int maxOrdinal = 0; for (UTsize i = 0; i < allMembers.size(); i++) { MemberInfo *mi = allMembers.at(i); if (mi->getOrdinal() > maxOrdinal) { maxOrdinal = mi->getOrdinal(); } } // and assign int start = maxOrdinal + 1; for (UTsize i = 0; i < allMembers.size(); i++) { MemberInfo *mi = allMembers.at(i); if (!mi->ordinal) { lmAssert(mi->getDeclaringType() == this, "ordinal being assigned to non-declared member"); UTsize j; for (j = 0; j < allMembers.size(); j++) { MemberInfo *other = allMembers.at(j); if (other->getDeclaringType() == this) { continue; } if (strcmp(other->getName(), mi->getName())) { continue; } break; } if (j == allMembers.size()) { mi->setOrdinal(start++); } else { mi->setOrdinal(allMembers.at(j)->getOrdinal()); } } } }
Expression *TypeCompiler::visit(SuperExpression *expression) { lmAssert(currentMethod, "super outside of method"); Type *type = currentMethod->getDeclaringType(); Type *baseType = type->getBaseType(); //FIXME: issue a warning if (!baseType) { return expression; } FuncState *fs = cs->fs; if (currentMethod->isConstructor()) { ConstructorInfo *base = baseType->getConstructor(); //FIXME: warn if no base constructor if (!base) { return expression; } // load up base class ExpDesc eclass; BC::singleVar(cs, &eclass, baseType->getFullName().c_str()); // index with the __ls_constructor BC::expToNextReg(fs, &eclass); ExpDesc fname; BC::expString(cs, &fname, "__ls_constructor"); BC::expToNextReg(fs, &fname); BC::expToVal(fs, &fname); BC::indexed(fs, &eclass, &fname); // call the LSMethod generateCall(&eclass, &expression->arguments); } else { utString name = currentMethod->getName(); if (expression->method) { name = expression->method->string; } MemberInfo *mi = baseType->findMember(name.c_str()); //FIXME: warn if (!mi) { return expression; } lmAssert(mi->isMethod(), "Non-method in super call"); MethodInfo *methodInfo = (MethodInfo *)mi; // load up declaring class ExpDesc eclass; BC::singleVar(cs, &eclass, methodInfo->getDeclaringType()->getFullName().c_str()); BC::expToNextReg(fs, &eclass); ExpDesc fname; BC::expString(cs, &fname, name.c_str()); BC::expToNextReg(fs, &fname); BC::expToVal(fs, &fname); BC::indexed(fs, &eclass, &fname); // call the LSMethod generateCall(&eclass, &expression->arguments); expression->e = eclass; } return expression; }
Expression *TypeCompiler::visit(AssignmentOperatorExpression *expression) { Tokens *tok = Tokens::getSingletonPtr(); BinOpr op = getassignmentopr(expression->type); lmAssert(op != OPR_NOBINOPR, "Unknown bin op on AssignentOperatorExpression"); Expression *eleft = expression->leftExpression; Expression *eright = expression->rightExpression; lmAssert(eleft->type, "Untyped error on left expression"); const char *opmethod = tok->getOperatorMethodName(expression->type); if (opmethod) { MemberInfo *mi = eleft->type->findMember(opmethod); if (mi) { lmAssert(mi->isMethod(), "Non-method operator"); MethodInfo *method = (MethodInfo *)mi; lmAssert(method->isOperator(), "Non-operator method"); utArray<Expression *> args; args.push_back(eright); ExpDesc opcall; ExpDesc emethod; eleft->visitExpression(this); opcall = eleft->e; BC::initExpDesc(&emethod, VKNUM, 0); emethod.u.nval = method->getOrdinal(); BC::expToNextReg(cs->fs, &opcall); BC::expToNextReg(cs->fs, &emethod); BC::expToVal(cs->fs, &emethod); BC::indexed(cs->fs, &opcall, &emethod); generateCall(&opcall, &args, method); expression->e = opcall; return expression; } } eleft->assignment = false; eleft->visitExpression(this); BC::infix(cs->fs, op, &eleft->e); eright->visitExpression(this); BC::expToNextReg(cs->fs, &eright->e); BC::posFix(cs->fs, op, &eleft->e, &eright->e); ExpDesc right = eleft->e; BC::expToNextReg(cs->fs, &right); memset(&eleft->e, 0, sizeof(ExpDesc)); eleft->assignment = true; eleft->visitExpression(this); ExpDesc left = eleft->e; if (eleft->memberInfo && eleft->memberInfo->isProperty()) { eright->e = right; generatePropertySet(&eleft->e, eright, false); } else { BC::storeVar(cs->fs, &left, &right); } return expression; }
void LSLuaState::cacheAssemblyTypes(Assembly *assembly, utArray<Type *>& types) { // setup assembly type lookup field lua_rawgeti(L, LUA_GLOBALSINDEX, LSASSEMBLYLOOKUP); lua_pushlightuserdata(L, assembly); lua_setfield(L, -2, assembly->getName().c_str()); lua_pop(L, 1); assembly->ordinalTypes = new Type *[types.size() + 1]; for (UTsize j = 0; j < types.size(); j++) { Type *type = types.at(j); assembly->types.insert(type->getName(), type); lmAssert(type->getTypeID() > 0 && type->getTypeID() <= (LSTYPEID)types.size(), "LSLuaState::cacheAssemblyTypes TypeID out of range"); assembly->ordinalTypes[type->getTypeID()] = type; const char *typeName = type->getFullName().c_str(); // fast access cache if (!strcmp(typeName, "system.Object")) { objectType = type; } else if (!strcmp(typeName, "system.Null")) { nullType = type; } else if (!strcmp(typeName, "system.Boolean")) { booleanType = type; } else if (!strcmp(typeName, "system.Number")) { numberType = type; } else if (!strcmp(typeName, "system.String")) { stringType = type; } else if (!strcmp(typeName, "system.Function")) { functionType = type; } else if (!strcmp(typeName, "system.Vector")) { vectorType = type; } lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMEMBERINFONAME); lua_pushlightuserdata(L, type); lua_gettable(L, -2); // cache all members for fast lookup of memberinfo -> pre-interned // lua string (interning strings is the devil's work) if (lua_isnil(L, -1)) { lua_pop(L, 1); utArray<MemberInfo *> members; MemberTypes types; types.method = true; types.field = true; types.property = true; type->findMembers(types, members, false); // cache the type to member info table lua_pushlightuserdata(L, type); lua_pushstring(L, type->getName()); lua_settable(L, -3); for (UTsize i = 0; i < members.size(); i++) { MemberInfo *mi = members.at(i); lua_pushlightuserdata(L, mi); lua_pushstring(L, mi->getName()); lua_settable(L, -3); } } else { lua_pop(L, 1); } lua_pop(L, 1); // if we weren't cached during assembly load, cache now if (!typeCache.get(type->getFullName())) { typeCache.insert(type->getFullName(), type); } } lmAssert(nullType, "LSLuaState::cacheAssemblyTypes - system.Null not found"); lmAssert(booleanType, "LSLuaState::cacheAssemblyTypes - system.Boolean not found"); lmAssert(numberType, "LSLuaState::cacheAssemblyTypes - system.Number not found"); lmAssert(stringType, "LSLuaState::cacheAssemblyTypes - system.String not found"); lmAssert(functionType, "LSLuaState::cacheAssemblyTypes - system.Function not found"); lmAssert(vectorType, "LSLuaState::cacheAssemblyTypes - system.Vector not found"); }
static int lsr_instanceindex(lua_State *L) { // we hit the instance index metamethod when we can't find a value // in the instance's table, this is a native or a bound method lua_rawgeti(L, 1, LSINDEXTYPE); Type *type = (Type *)lua_topointer(L, -1); lua_pop(L, 1); lmAssert(type, "Missing type on instance index"); if (lua_isnumber(L, 2)) { int ordinal = (int)lua_tonumber(L, 2); MemberInfo *mi = type->getMemberInfoByOrdinal(ordinal); lmAssert(mi, "Unable to find ordinal %s %i", type->getFullName().c_str(), ordinal); if (mi->isStatic()) { lua_rawgeti(L, 1, LSINDEXCLASS); lua_replace(L, 1); lua_gettable(L, 1); return 1; } // we need to look in the class, the result will be cached to instance MethodBase *method = NULL; if (mi->isMethod()) { method = (MethodBase *)mi; } if (method) { lua_rawgeti(L, 1, LSINDEXCLASS); assert(!lua_isnil(L, -1)); int clsIdx = lua_gettop(L); if (!method->isStatic()) { if (method->isFastCall()) { // get the fast call structure pointer lua_pushlightuserdata(L, method->getFastCall()); // get the the "this" if (lua_type(L, 1) == LUA_TTABLE) { lua_rawgeti(L, 1, LSINDEXNATIVE); } else { lua_pushvalue(L, 1); } // unwrap this Detail::UserdataPtr *p1 = (Detail::UserdataPtr *)lua_topointer(L, -1); lua_pushlightuserdata(L, p1->getPointer()); lua_replace(L, -2); lua_pushnumber(L, ordinal); lua_gettable(L, clsIdx); } else { lua_pushlightuserdata(L, method); lua_pushvalue(L, 1); lua_pushnumber(L, ordinal); lua_gettable(L, clsIdx); } assert(!lua_isnil(L, -1)); int nup = 3; int fd = method->getFirstDefaultParm(); if (fd != -1) { utString dname; if (method->isConstructor()) { dname = "__ls_constructor"; } else { dname = method->getName(); } dname += "__default_args"; lua_getfield(L, clsIdx, dname.c_str()); int dargs = lua_gettop(L); for (int i = fd; i < method->getNumParameters(); i++) { lua_pushnumber(L, i); lua_gettable(L, dargs); nup++; } lua_remove(L, dargs); } // check for fast path if (method->isFastCall()) { if (method->getNumParameters()) { // setter lua_pushcclosure(L, lsr_method_fastcall_set, nup); } else { // getter lua_pushcclosure(L, lsr_method_fastcall_get, nup); } } else { // bind the instance method lua_pushcclosure(L, lsr_method, nup); } // store to method lookup, this is worth it // as only happens once per instance method bind // and can now lookup MethodBase on any function // in one table lookup lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMETHODLOOKUP); lua_pushvalue(L, -2); lua_pushlightuserdata(L, method); lua_rawset(L, -3); lua_pop(L, 1); // cache to instance lua_pushvalue(L, -1); lua_rawseti(L, 1, ordinal); return 1; } else { assert(0); } } FieldInfo *field = NULL; if (mi->isField()) { field = (FieldInfo *)mi; } if (field && field->isNative()) { // for primitive fields, we could generate // a direct lookup in the LSINDEXNATIVE table // in bytecode gen, however this only saves for // native vars and not properties // (which should be using fast path anyway and complicates bytecode) // get the native userdata lua_rawgeti(L, 1, LSINDEXNATIVE); lua_pushnumber(L, field->getOrdinal()); lua_gettable(L, -2); // if we are native we need to wrap if (lua_isuserdata(L, -1)) { lualoom_pushnative_userdata(L, field->getType(), -1); } return 1; } // if we get here the value actually is null lua_pushnil(L); return 1; } // if we hit here, this should be an interface access where we have to // look up by string (and cache as these are only ever instance methods) const char *name = lua_tostring(L, 2); const char *pname = name; MemberInfo *mi = NULL; if (!strncmp(name, "__pget_", 7)) { pname = &name[7]; mi = type->findMember(pname, true); lmAssert(mi && mi->isProperty(), "Could not find property getter for '%s' on type '%s'", pname, type->getFullName().c_str()); mi = ((PropertyInfo *)mi)->getGetMethod(); lmAssert(mi, "Found NULL property getter for '%s' on type '%s'", pname, type->getFullName().c_str()); } else if (!strncmp(name, "__pset_", 7)) { pname = &name[7]; mi = type->findMember(pname, true); lmAssert(mi && mi->isProperty(), "Could not find property setter for '%s' on type '%s'", pname, type->getFullName().c_str()); mi = ((PropertyInfo *)mi)->getSetMethod(); lmAssert(mi, "Found NULL property setter for '%s' on type '%s'", pname, type->getFullName().c_str()); } else { mi = type->findMember(name, true); lmAssert(mi, "Unable to find member '%s' via string on instance of type %s", name, type->getFullName().c_str()); assert(mi); assert(mi->isMethod()); assert(mi->getOrdinal()); } lua_pushnumber(L, mi->getOrdinal()); lua_gettable(L, 1); lua_pushstring(L, name); lua_pushvalue(L, -2); lua_rawset(L, 1); return 1; }
void cGuild::load( const QSqlQuery& result ) { serial_ = result.value( 0 ).toInt(); name_ = result.value( 1 ).toString(); abbreviation_ = result.value( 2 ).toString(); charta_ = result.value( 3 ).toString(); website_ = result.value( 4 ).toString(); alignment_ = ( eAlignment ) result.value( 5 ).toInt(); leader_ = dynamic_cast<P_PLAYER>( World::instance()->findChar( result.value( 6 ).toInt() ) ); founded_.setTime_t( result.value( 7 ).toInt() ); guildstone_ = World::instance()->findItem( result.value( 8 ).toInt() ); // Load members and canidates QSqlQuery members( QString( "SELECT player,showsign,guildtitle,joined FROM guilds_members WHERE guild = %1" ).arg( serial_ ) ); while ( members.next() ) { P_PLAYER player = dynamic_cast<P_PLAYER>( World::instance()->findChar( members.value( 0 ).toInt() ) ); if ( player ) { player->setGuild( this ); members_.append( player ); MemberInfo* info = new MemberInfo; info->setShowSign( members.value( 1 ).toInt() != 0 ); info->setGuildTitle( members.value( 2 ).toString() ); info->setJoined( members.value( 3 ).toInt() ); memberinfo_.insert( player, info ); } } QSqlQuery canidates( QString( "SELECT player FROM guilds_canidates WHERE guild = %1" ).arg( serial_ ) ); while ( canidates.next() ) { P_PLAYER player = dynamic_cast<P_PLAYER>( World::instance()->findChar( canidates.value( 0 ).toInt() ) ); if ( player ) { player->setGuild( this ); canidates_.append( player ); } } // Clear the leader if he's not a member of the guild if ( !members_.contains( leader_ ) ) { leader_ = 0; } Guilds::instance()->registerGuild( this ); QSqlQuery allies( QString( "SELECT ally FROM guilds_allies WHERE guild = %1" ).arg( serial_ ) ); while ( allies.next() ) { allies_.append( allies.value( 0 ).toInt() ); } QSqlQuery enemies( QString( "SELECT enemy FROM guilds_enemies WHERE guild = %1" ).arg( serial_ ) ); while ( enemies.next() ) { enemies_.append( enemies.value( 0 ).toInt() ); } }