Ejemplo n.º 1
0
	void Door::interact(const Entity *interactor) {
		DoorState target;

		if(isOpened())
			target = DoorState::closed;
		else {
			if(!m_key.isDummy()) {
				const Actor *actor = dynamic_cast<const Actor*>(interactor);
				if(!actor || actor->inventory().find(m_key) == -1) {
					printf("Key required!\n");
					return;
				}
			}

			target = classId() == DoorClassId::rotating_out? DoorState::opened_out : DoorState::opened_in;
			if(classId() == DoorClassId::rotating && interactor) {
				float3 interactor_pos = interactor->boundingBox().center();
				float3 dir = boundingBox().center() - interactor_pos;
				if(dot(dir.xz(), m_open_in_dir) < 0.0f)
					target = DoorState::opened_out;
			}
		}
		
		changeState(target);
		//TODO: open direction should depend on interactor's position		
	}
inline bool HTMLObjectElement::hasValidClassId()
{
    // HTML5 says that fallback content should be rendered if a non-empty
    // classid is specified for which the UA can't find a suitable plug-in.
    // WebKit supports no classids, with the exception of Qt plug-ins, which use
    // classid to specify which QObject to load.
#if PLATFORM(QT)
    return classId().isEmpty() || equalIgnoringCase(serviceType(), "application/x-qt-plugin") || equalIgnoringCase(serviceType(), "application/x-qt-styled-widget");
#else
    return classId().isEmpty();
#endif
}
Ejemplo n.º 3
0
bool HTMLObjectElement::hasValidClassId()
{
    if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) && classId().startsWith("java:", false))
        return true;
    
    if (shouldAllowQuickTimeClassIdQuirk())
        return true;

    // HTML5 says that fallback content should be rendered if a non-empty
    // classid is specified for which the UA can't find a suitable plug-in.
    return classId().isEmpty();
}
bool HTMLObjectElement::hasValidClassId()
{
#if PLATFORM(QT)
    if (equalIgnoringCase(serviceType(), "application/x-qt-plugin") || equalIgnoringCase(serviceType(), "application/x-qt-styled-widget"))
        return true;
#endif

    if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) && classId().startsWith("java:", false))
        return true;

    // HTML5 says that fallback content should be rendered if a non-empty
    // classid is specified for which the UA can't find a suitable plug-in.
    return classId().isEmpty();
}
Ejemplo n.º 5
0
	void Door::onImpact(DamageType damage_type, float damage, const float3 &force, EntityRef source) {
		if(!isOpened() && damage_type == DamageType::bludgeoning) {
			float door_force = dot(force.xz(), m_open_in_dir);
			if(fabs(door_force) >= 8.0f && classId() != DoorClassId::sliding) {
				bool opening_in = door_force > 0.0f;

				if(classId() == DoorClassId::rotating_in && !opening_in)
					return;
				if(classId() == DoorClassId::rotating_out && opening_in)
					return;

				changeState(opening_in? DoorState::opened_in : DoorState::opened_out);
			}
		}
	}
Ejemplo n.º 6
0
	void Door::changeState(DoorState target) {
		DoorState result = m_state;

		for(int n = 0; n < arraySize(s_transitions); n++)
			if(s_transitions[n].current == m_state && s_transitions[n].target == target) {
				result = s_transitions[n].result;
				break;
			}
		if(result == m_state)
			return;

		FBox bbox = computeBBox(result);
		bbox.min += float3(1.1f, 0.1f, 1.1f);
		bbox.max -= float3(1.1f, 0.1f, 1.1f);

		bool is_colliding = (bool)findAny(bbox + pos(), {Flags::entity | Flags::colliding, ref()});

		if(is_colliding && classId() == DoorClassId::rotating && m_state == DoorState::closed && target == DoorState::opened_in) {
			target = DoorState::opened_out;
			result = DoorState::opening_out;
			bbox = computeBBox(result);
			is_colliding = (bool)findAny(bbox + pos(), {Flags::entity | Flags::colliding, ref()});
		}
		if(!is_colliding) {
			m_bbox = bbox;
			m_state = result;
			m_update_anim = true;
		}
	}
Ejemplo n.º 7
0
bool // result undefined if class names are not all unique
SmokeObject::instanceOf(const char *className) const {
  Smoke *smoke = this->smoke();
  // the base class must be 'found', i.e., it cannot be external
  Smoke::ModuleIndex other = smoke->findClass(className);
  return smoke->isDerivedFrom(smoke, classId(), other.smoke, other.index);
}
Ejemplo n.º 8
0
    void BehaviorTask::load(ISerializableNode* node)
    {
        CSerializationID  attrId("status");
        behaviac::string attrStr;

        if (node->getAttr(attrId, attrStr))
        {
            behaviac::StringUtils::FromString(attrStr.c_str(), this->m_status);
        }

#if !BEHAVIAC_RELEASE

        if (this->m_status != BT_INVALID)
        {
            CSerializationID  classId("class");
            node->getAttr(classId, attrStr);
            BEHAVIAC_ASSERT(attrStr == this->GetClassNameString());

            CSerializationID  idId("id");
            node->getAttr(idId, attrStr);
            int id = -1;
            StringUtils::FromString(attrStr.c_str(), id);
            BEHAVIAC_ASSERT(id == this->GetId());
        }

#endif
    }
Ejemplo n.º 9
0
/* Cast the instance pointer to a parent class. This is necessary,
   because the compiler does not know how to cast a void* to a parent
   class when multiple inheritance is involved.
*/
void *
SmokeObject::castPtr(const char *className, bool clone) const {
  Smoke *smoke = this->smoke();
  // Be very careful changing this -- it is written as intended
  return smoke->cast(clone ? clonePtr() : _ptr, classId(),
                     smoke->idClass(className, true).index);
}
Ejemplo n.º 10
0
bool HTMLObjectElement::shouldAllowQuickTimeClassIdQuirk()
{
    // This site-specific hack maintains compatibility with Mac OS X Wiki Server,
    // which embeds QuickTime movies using an object tag containing QuickTime's
    // ActiveX classid. Treat this classid as valid only if OS X Server's unique
    // 'generator' meta tag is present. Only apply this quirk if there is no
    // fallback content, which ensures the quirk will disable itself if Wiki
    // Server is updated to generate an alternate embed tag as fallback content.
    if (!document()->page()
        || !document()->page()->settings()->needsSiteSpecificQuirks()
        || hasFallbackContent()
        || !equalIgnoringCase(classId(), "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"))
        return false;

    RefPtr<NodeList> metaElements = document()->getElementsByTagName(HTMLNames::metaTag.localName());
    unsigned length = metaElements->length();
    for (unsigned i = 0; i < length; ++i) {
        ASSERT(metaElements->item(i)->isHTMLElement());
        HTMLMetaElement* metaElement = static_cast<HTMLMetaElement*>(metaElements->item(i));
        if (equalIgnoringCase(metaElement->name(), "generator") && metaElement->content().startsWith("Mac OS X Server Web Services Server", false))
            return true;
    }
    
    return false;
}
Ejemplo n.º 11
0
	MonoClass* MonoAssembly::getClass(const String& ns, const String& typeName, ::MonoClass* rawMonoClass) const
	{
		if (!mIsLoaded)
			BS_EXCEPT(InvalidStateException, "Trying to use an unloaded assembly.");

		if (rawMonoClass == nullptr)
			return nullptr;

		auto iterFind = mClassesByRaw.find(rawMonoClass);

		if (iterFind != mClassesByRaw.end())
			return iterFind->second;

		MonoClass* newClass = new (bs_alloc<MonoClass>()) MonoClass(ns, typeName, rawMonoClass, this);

		mClassesByRaw[rawMonoClass] = newClass;

		if (!isGenericClass(typeName)) // No point in referencing generic types by name as all instances share it
		{
			MonoAssembly::ClassId classId(ns, typeName);
			mClasses[classId] = newClass;
		}

		return newClass;
	}
Ejemplo n.º 12
0
	void Door::initializeOpenDir() {
		float3 center = computeBBox(DoorState::closed).center();
		
		if(classId() == DoorClassId::rotating_in)
			m_open_in_dir = (computeBBox(DoorState::opening_in).center() - center).xz();
		else
			m_open_in_dir = -(computeBBox(DoorState::opening_out).center() - center).xz();
		m_open_in_dir = m_open_in_dir / length(m_open_in_dir);
	}
Ejemplo n.º 13
0
	void Door::onAnimFinished() {
		for(int n = 0; n < arraySize(s_transitions); n++)
			if(m_state == s_transitions[n].result) {
				m_state = s_transitions[n].target;
				m_bbox = computeBBox(m_state);
				m_update_anim = true;
				if(m_state == DoorState::opened_in && classId() == DoorClassId::sliding)
					m_close_time = currentTime() + 3.0;
				break;
			}
	}
Ejemplo n.º 14
0
bool HTMLObjectElement::hasValidClassId()
{
#if PLATFORM(QT)
    if (equalIgnoringCase(serviceType(), "application/x-qt-plugin") || equalIgnoringCase(serviceType(), "application/x-qt-styled-widget"))
        return true;
	//+EAWebKitChange
	//10/14/2011 - Do we really need this change?
#elif PLATFORM(EA)
	if (equalIgnoringCase(serviceType(), "application/x-ea-plugin") || equalIgnoringCase(serviceType(), "application/x-ea-styled-widget"))
		return true;
#endif
	//-EAWebKitChange

    if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) && classId().startsWith("java:", false))
        return true;
    
    if (shouldAllowQuickTimeClassIdQuirk())
        return true;

    // HTML5 says that fallback content should be rendered if a non-empty
    // classid is specified for which the UA can't find a suitable plug-in.
    return classId().isEmpty();
}
Ejemplo n.º 15
0
    void BehaviorTask::save(ISerializableNode* node) const
    {
        if (this->m_status != BT_INVALID)
        {
            CSerializationID  classId("class");
            node->setAttr(classId, this->GetClassNameString());

            CSerializationID  idId("id");
            node->setAttr(idId, this->GetId());

            CSerializationID  statusId("status");
            node->setAttr(statusId, this->m_status);
        }
    }
Ejemplo n.º 16
0
	FBox Door::computeBBox(DoorState state) const {	
		float3 size = (float3)m_sprite.bboxSize();
		float maxs = max(size.x, size.z);
		
		FBox box;
		if(classId() == DoorClassId::sliding || state == DoorState::closed)
			box = FBox(float3(0, 0, 0), state == DoorState::opened_in? float3(0, 0, 0) : size);
		else if(state == DoorState::closing_in || state == DoorState::opening_in)
			box = FBox(-maxs + 1, 0, 0, 1, size.y, maxs);
		else if(state == DoorState::closing_out || state == DoorState::opening_out)
			box = FBox(0, 0, 0, maxs, size.y, maxs);
		else if(state == DoorState::opened_out)
			box = FBox(0, 0, 0, size.z, size.y, size.x);
		else if(state == DoorState::opened_in)
			box = FBox(-size.z + 1, 0, 0, 1, size.y, size.x);

		//TODO: this is still wrong
		FBox out = rotateY(box, size * 0.5f, dirAngle());
		out.min = (float3)(int3)out.min;
		out.max = (float3)(int3)out.max;
		DASSERT(classId() == DoorClassId::sliding || !out.empty());
		return out;
	}
Ejemplo n.º 17
0
void AddLegDialogWidget::onCompetitorSelected()
{
	qf::core::utils::TableRow row = ui->tblCompetitors->selectedRow();
	//int curr_leg = row.value("runs.leg").toInt();
	int competitor_id = row.value("competitors.id").toInt();
	int siid = row.value("competitors.siid").toInt();
	int curr_run_id = row.value("runs.id").toInt();
	int curr_relay_id = row.value("relayId").toInt();
	if(curr_relay_id > 0 && curr_relay_id != relayId()) {
		if(false == qf::qmlwidgets::dialogs::MessageBox::askYesNo(this, tr("Competitor has different relay assigned already. Move it to current one?")))
			return;
		if(row.value("relays.classId").toInt() != classId()) {
			qf::core::sql::Query q;
			q.exec("UPDATE competitors SET "
				   "classId=" + QString::number(classId())
				   + " WHERE id=" + QString::number(competitor_id), qf::core::Exception::Throw);
		}
	}
	int free_leg = findFreeLeg();
	qf::core::sql::Query q;
	if(curr_run_id == 0 || curr_relay_id == relayId()) {
		q.exec("INSERT INTO runs (competitorId, relayId, leg, siid) VALUES ("
			   + QString::number(competitor_id) + ", "
			   + QString::number(relayId()) + ", "
			   + QString::number(free_leg) + ", "
			   + QString::number(siid) + " "
			   + ") ", qf::core::Exception::Throw);
	}
	else {
		q.exec("UPDATE runs SET "
			   "relayId=" + QString::number(relayId())
			   + ", leg=" + QString::number(free_leg)
			   + ", isRunning=(1=1)" // TRUE is not accepted by SQLite
			   + " WHERE id=" + QString::number(curr_run_id), qf::core::Exception::Throw);
	}
	emit legAdded();
}
// FIXME: This should be unified with HTMLEmbedElement::updateWidget and
// moved down into HTMLPluginImageElement.cpp
void HTMLObjectElement::updateWidget(bool onlyCreateNonNetscapePlugins)
{
    ASSERT(!renderEmbeddedObject()->pluginCrashedOrWasMissing());
    // FIXME: We should ASSERT(needsWidgetUpdate()), but currently
    // FrameView::updateWidget() calls updateWidget(false) without checking if
    // the widget actually needs updating!
    setNeedsWidgetUpdate(false);
    // FIXME: This should ASSERT isFinishedParsingChildren() instead.
    if (!isFinishedParsingChildren())
        return;

    String url = this->url();
    
    // If the object does not specify a MIME type via a type attribute, but does
    // contain a classid attribute, try to map the classid to a MIME type.
    String serviceType = this->serviceType();
    if (serviceType.isEmpty())
        serviceType = serviceTypeForClassId(classId());

    // FIXME: These should be joined into a PluginParameters class.
    Vector<String> paramNames;
    Vector<String> paramValues;
    parametersForPlugin(paramNames, paramValues, url, serviceType);

    // Note: url is modified above by parametersForPlugin.
    if (!allowedToLoadFrameURL(url))
        return;

    bool fallbackContent = hasFallbackContent();
    renderEmbeddedObject()->setHasFallbackContent(fallbackContent);

    if (onlyCreateNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType))
        return;

    bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url);

    // beforeload events can modify the DOM, potentially causing
    // RenderWidget::destroy() to be called.  Ensure we haven't been
    // destroyed before continuing.
    // FIXME: Should this render fallback content?
    if (!renderer())
        return;

    SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
    bool success = beforeLoadAllowedLoad && loader->requestObject(this, url, getAttribute(nameAttr), serviceType, paramNames, paramValues);

    if (!success && fallbackContent)
        renderFallbackContent();
}
Ejemplo n.º 19
0
//------------------------------------------------------------------------
void CVehicleDamages::ParseDamageMultipliers(TDamageMultipliers& multipliersByHitType, TDamageMultipliers& multipliersByProjectile, const CVehicleParams& table)
{
	CVehicleParams damageMultipliersTable = table.findChild("DamageMultipliers");
	if (!damageMultipliersTable)
		return;

	int i = 0;
	int c = damageMultipliersTable.getChildCount();
	
	IGameRules* pGR = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();
	assert(pGR);

	for (; i < c; i++)
	{
		if (CVehicleParams multiplierTable = damageMultipliersTable.getChild(i))
		{
			string damageType = multiplierTable.getAttr("damageType");
			if (!damageType.empty())
			{
				int hitTypeId = 0;
				if(pGR && damageType != "default")
					hitTypeId = pGR->GetHitTypeId(damageType.c_str());

				assert(hitTypeId != 0 || damageType == "default");
				
				if(hitTypeId != 0 || damageType == "default")
				{
					GetAndInsertMultiplier( multipliersByHitType, multiplierTable, int(hitTypeId) );
				}
			}		

			string ammoType = multiplierTable.getAttr("ammoType");
		  if (!ammoType.empty())
			{
				int projectileType = 0;
				if(pGR && ammoType != "default")
				{
					uint16 classId(~uint16(0));

					if( ammoType == "default" || gEnv->pGame->GetIGameFramework()->GetNetworkSafeClassId(classId, ammoType.c_str()) )
					{
						GetAndInsertMultiplier( multipliersByProjectile, multiplierTable, int(classId) );
					}
				}
			}				
		}
	}
}
Ejemplo n.º 20
0
void
SmokeObject::invokeMethod(const char *name, Smoke::Stack stack) {
  Smoke *smoke = this->smoke();
  Smoke::ModuleIndex nameId = smoke->idMethodName(name);
  Smoke::ModuleIndex classIdx = Smoke::ModuleIndex(smoke, classId());
  Smoke::ModuleIndex meth = nameId.smoke->findMethod(classIdx, nameId);
  if (meth.index > 0) {
    Smoke::Method &m =
      meth.smoke->methods[meth.smoke->methodMaps[meth.index].method];
    Smoke::ClassFn fn = meth.smoke->classes[m.classId].classFn;
    (*fn)(m.method, _ptr, stack);
  } else {
    error("Cannot find (unambiguous) %s::%s",
          smoke->classes[classIdx.index].className, name);
  }
}
void CNcdNodeContentInfoProxy::InternalizeDataL( RReadStream& aStream )
    {
    DLTRACEIN((""));

    // First read the class id. Because, it is the first thing in the stream.
    TInt classId( aStream.ReadInt32L() );
    
    if ( classId != NcdNodeClassIds::ENcdNodeContentInfoClassId )
        {
        // classId is not recognized
        DLERROR(("Class id was not recognized!"));
        // For testing purposes assert here
        DASSERT( EFalse );
        
        // Otherwise leave is adequate
        User::Leave( KErrCorrupt );
        }

    iPurpose = aStream.ReadUint16L();
    DLINFO(( "Purpose: %u", iPurpose ));
    
    InternalizeDesL( iMimeType, aStream );    
    DLINFO(( _L("Mime: %S"), iMimeType ));
    
    //The Internalization here must be consistant with the externalization in CNcdNodeContentInfo
    if ( iMimeType->Compare( KMimeTypeMatchWidget ) == 0 )
        {
        //widget
        InternalizeDesL( iIdentifier, aStream );
        }
    else
        {
        //sis
        iUid.iUid = aStream.ReadInt32L();   
        DLINFO(( "Uid: %x", iUid.iUid )); 
        }
   
    InternalizeDesL( iVersion, aStream );    
    DLINFO(( _L("Version: %S"), iVersion ));

    iSize = aStream.ReadInt32L();
    DLINFO(( _L("Size: %d"), iSize ));
    
    DLTRACEOUT((""));
    }
Ejemplo n.º 22
0
void AppInstance::setClassId( QString classid )
{
    AppClass *app_class;

    if( classid == classId() ) return;
    if( appLibrary() )
        appLibrary()->id().postLibEvent( new EventDestroyInstance(id()) );
    class_id_ = classid;
    app_class = AppLibrary::getClass(classid);
    if( app_class )
    {
        class_size_ = app_class->size();
        setParent( app_class->parent() );
        appLibrary()->id().postLibEvent( new EventCreateInstance( app_class->id(), id(), objectName() ) );
    }

    return;
}
Ejemplo n.º 23
0
	void Door::think() {
		const float2 dir = actualDir();
		
		if(m_update_anim) {
			replicate();
			playSequence(m_proto.seq_ids[m_state]);
			m_update_anim = false;
		}
		if(classId() == DoorClassId::sliding && m_state == DoorState::opened_in && currentTime() > m_close_time) {
			FBox bbox = computeBBox(DoorState::closed);
			if((bool)findAny(bbox + pos(), {Flags::entity | Flags::colliding, ref()})) {
				m_close_time = currentTime() + 1.5;
			}
			else {
				m_bbox = bbox;
				m_state = DoorState::closing_in;
				m_update_anim = true;
			}
		}
	}
Ejemplo n.º 24
0
void AddLegDialogWidget::onRegistrationSelected()
{
	qf::core::utils::TableRow row = ui->tblRegistrations->selectedRow();
	Competitors::CompetitorDocument doc;
	doc.loadForInsert();
	doc.setValue("firstName", row.value("firstName"));
	doc.setValue("lastName", row.value("lastName"));
	doc.setValue("registration", row.value("registration"));
	doc.setValue("licence", row.value("licence"));
	doc.setValue("siid", row.value("siid"));
	doc.setValue("classId", classId());
	doc.save();
	int run_id = doc.lastInsertedRunsIds().value(0);
	QF_ASSERT(run_id > 0, "Bad insert", return);
	int free_leg = findFreeLeg();
	qf::core::sql::Query q;
	q.exec("UPDATE runs SET relayId=" + QString::number(relayId()) + ", leg=" + QString::number(free_leg)
		   + " WHERE id=" + QString::number(run_id), qf::core::Exception::Throw);
	emit legAdded();
}
Ejemplo n.º 25
0
void CNcdNodePreview::InternalizeL( RReadStream& aStream )
    {
    DLTRACEIN((""));

    // Read the class id first because it is set to the stream in internalize
    // function and it is not read from the stream anywhere else.
    TInt classId( aStream.ReadInt32L() );
    if ( classId != ClassId() )
        {
        DLERROR(("Wrong class id"));
        DASSERT( EFalse );
        // Leave because the stream does not match this class object
        User::Leave( KErrCorrupt );
        }
    
    iFileCount = aStream.ReadInt16L();

    HBufC* previewMimeType = 0;
    iPreviewMimeTypes.ResetAndDestroy();
    for( int i = 0; i < iFileCount; i++ )
        {
        InternalizeDesL( previewMimeType, aStream );
        CleanupStack::PushL( previewMimeType );
        iPreviewMimeTypes.AppendL( previewMimeType );
        CleanupStack::Pop( previewMimeType );
        }
        
    HBufC* uri = 0;
    iUris.ResetAndDestroy();
    for( int i = 0; i < iFileCount; i++ )
        {
        InternalizeDesL( uri, aStream );
        CleanupStack::PushL( uri );
        iUris.AppendL( uri );
        CleanupStack::Pop( uri );
        }
    
    // Try to update MIME from downloaded previews
    UpdateMimesFromPreviewManagerL();
    DLTRACEOUT((""));
    }
Ejemplo n.º 26
0
void W32StandardControl::allocate(WORD *&p, short &id) const {
	*p++ = LOWORD(myStyle);
	*p++ = HIWORD(myStyle);
	*p++ = 0;
	*p++ = 0;
	*p++ = myX;
	*p++ = myY;
	/*
	if ((mySize.Width == 0) || (mySize.Height == 0)) {
		mySize = minimumSize();
	}
	*/
	*p++ = mySize.Width;
	*p++ = mySize.Height;
	*p++ = id++;
	*p++ = 0xFFFF;
	*p++ = classId();
	*p++ = 0;
	*p++ = 0;
	*p++ = 0;
}
Ejemplo n.º 27
0
	MonoClass* MonoAssembly::getClass(const String& namespaceName, const String& name) const
	{
		if(!mIsLoaded)
			BS_EXCEPT(InvalidStateException, "Trying to use an unloaded assembly.");

		MonoAssembly::ClassId classId(namespaceName, name);
		auto iterFind = mClasses.find(classId);

		if(iterFind != mClasses.end())
			return iterFind->second;

		::MonoClass* monoClass = mono_class_from_name(mMonoImage, namespaceName.c_str(), name.c_str());
		if(monoClass == nullptr)
			return nullptr;

		MonoClass* newClass = new (bs_alloc<MonoClass>()) MonoClass(namespaceName, name, monoClass, this);
		mClasses[classId] = newClass;
		mClassesByRaw[monoClass] = newClass;

		return newClass;
	}
Ejemplo n.º 28
0
bool
SmokeObject::instanceOf(const SmokeType &type) const {
  Smoke *smoke = this->smoke();
  return smoke->isDerivedFrom(smoke, classId(), type.smoke(), type.classId());
}
Ejemplo n.º 29
0
	bool Weapon::canKick() const {
		return isOneOf(classId(), WeaponClass::unarmed, WeaponClass::knife, WeaponClass::pistol, WeaponClass::club);
	}
Ejemplo n.º 30
0
// only works for pure Smoke instances, but that may be OK
void * SmokeObject::clonePtr() const {
  Smoke *smoke = this->smoke();
  const char *className = _klass->name();
  int classNameLen = strlen(className);

  // copy constructor signature
  QByteArray ccSig(className);
  int pos = ccSig.lastIndexOf("::");
  if (pos != -1) {
    ccSig = ccSig.mid(pos + strlen("::"));
  }
  ccSig.append("#");
  Smoke::ModuleIndex ccId = smoke->findMethodName(className, ccSig);

  char *ccArg = new char[classNameLen + 8];
  sprintf(ccArg, "const %s&", className);

  Smoke::ModuleIndex classIdx = Smoke::ModuleIndex(smoke, classId());
  Smoke::ModuleIndex ccMeth = smoke->findMethod(classIdx, ccId);

  if (ccMeth.index == 0) {
    qWarning("failed to construct copy: %s %p\n", className, _ptr);
    delete[] ccArg;
    return 0;
  }
  Smoke::Index method = ccMeth.smoke->methodMaps[ccMeth.index].method;
  if (method > 0) {
    delete[] ccArg;
    if (!(ccMeth.smoke->methods[method].flags & Smoke::mf_copyctor)) {
      qCritical("failed to construct copy: %s %p\n", className, _ptr);
      return 0;
    }
    ccMeth.index = method;
  } else {
    // ambiguous method, pick the copy constructor
    Smoke::Index i = -method;
    while (ccMeth.smoke->ambiguousMethodList[i]) {
      if (ccMeth.smoke->methods[ccMeth.smoke->ambiguousMethodList[i]].flags &
          Smoke::mf_copyctor)
        break;
      i++;
    }
    delete[] ccArg;
    ccMeth.index = ccMeth.smoke->ambiguousMethodList[i];
    if (ccMeth.index == 0) {
      qCritical("construct_copy() failed %s %p\n", className, _ptr);
      return 0;
    }
  }

  // Okay, ccMeth is the copy constructor. Time to call it.
  Smoke::StackItem args[2];
  args[0].s_voidp = 0;
  args[1].s_voidp = _ptr;
  Smoke::ClassFn fn = smoke->classes[classId()].classFn;
  (*fn)(smoke->methods[ccMeth.index].method, 0, args);

  // Initialize the binding for the new instance
  Smoke::StackItem s[2];
  s[1].s_voidp = module()->binding();
  (*fn)(0, args[0].s_voidp, s);

  return args[0].s_voidp;
}