Ejemplo n.º 1
0
// copies source nodes to be underneath this node
// branch is the location where detour is being introduced, so that we can see if slack times should be decreased
// returns whether or not copy was successful; if not successful, parent maybe should delete
bool TreeSlackNode :: copyNodes(vector<TreeSlackNode *> source, TreeSlackNode *branch, double detour) {
	bool fail = false;
	
	for(int i = 0; i < source.size(); i++) {
		TreeSlackNode *myCopy = constructCopy(this, source[i], branch, detour, shortestPath);
		
		if(myCopy) {
			children.push_back(myCopy);
		
			if(!myCopy->copyNodes(source[i]->children, branch, detour)) {
				//something's infeasible in our child's subtree, so delete child
				children.pop_back();
				fail = true;
			}
		} else {
			//child is infeasible, so fail
			fail = true;
		}
	}
	
	//determine whether or not copy was successful
	//we check the fail flag because we may not have had to copy any nodes at all
	if(fail && children.empty()) {
		return false;
	} else {
		return true;
	}
}
Ejemplo n.º 2
0
//attempt to insert new nodes into the tree
//doInsert will always be either size 2 containing a pickup and
// then a dropoff node, or size 1 and containing a dropoff
//the meaning of depth varies depending on if we're inserting pickup or dropoff
// pickup: distance from the root node
// dropoff: extra distance from the pickup node
bool TreeSlackNode :: insertNodes(vector<TreeSlackNode *> doInsert, double depth) {
	if(doInsert.size() > 0) {
		//try to create the first node to be inserted
		//for pickup nodes, the slack time is initialized to the pickup
		// constraint, so the detour introduced will be the distance from
		// the new node to the root node, or:
		//    depth + distance(here, new node)
		//for dropoff nodes, the slack time is how much extra distance to
		// the pickup node is tolerable, and the depth is set such that the
		// formula above will still work
		TreeSlackNode *insertCopy = constructCopy(this, doInsert[0], this, depth + shortestPath->shortestDistance(this->vert, doInsert[0]->vert), shortestPath);
		
		if(insertCopy) {
			bool fail = false;
			
			// first, copy other branches to our inserted copy
			vector<TreeSlackNode *> copySource;
			for(int i = 0; i < children.size(); i++) {
				copySource.clear();
				copySource.push_back(children[i]);
				
				//the child node will experience a detour between here and the
				// inserted node, and that detour will be equal to the time it
				// takes to go to the new node and back to the child minus the
				// time it takes to go directly from here to the child
				if(!(insertCopy->copyNodes(copySource, insertCopy, insertCopy->time + shortestPath->shortestDistance(insertCopy->vert, children[i]->vert) - children[i]->time))) {
					fail = true;
					break;
				}
			}
			
			if(!fail && doInsert.size() >= 2) {
				//if we haven't failed, we need to give to give the new node
				// the rest of the nodes to be inserted
				insertCopy->updateChildSlackTime();
				
				// give the insertCopy our doInsert, but with first element that was already copied by it removed
				vector<TreeSlackNode *> doInsertClone;
				for(int i = 1; i < doInsert.size(); i++) {
					doInsertClone.push_back(doInsert[i]);
				}
				
				// restart depth counter since this is the corresponding dropoff node
				// it's slack time is remaining service time, and so will only be affected by distance to the pickup node
				// we include the negative number because we only want to include EXTRA time from going directly in the detour
				if(!insertCopy->insertNodes(doInsertClone, -doInsertClone[0]->time)) {
					fail = true;
				}
			}
		
			// give other children our insertCopy in full
			// note that this must be executed after insertCopy updates because insertCopy copies nodes from these children
			for(int it = 0; it < children.size(); it++) {
				TreeSlackNode *child = children[it];
				
				if(!(child->insertNodes(doInsert, depth + child->time))) {
					// child failed, so delete from children
					delete child;
					children.erase(children.begin() + it);
					it--;
				}
			}
		
			if(!fail) {
				// lastly, insert insertCopy into our children (do this last so we don't push insertCopy into itself)
				children.push_back(insertCopy);
			} else if(children.empty()) {
				delete insertCopy;
				return false;
			} else {
				delete insertCopy;
			}
		} else {
			// if our inserted copy is not feasible, no other path will be feasible
			//  since we have to insert the same node to our children.. assuming shortest paths are shortest
			return false;
		}
	}
	
	return true;
}
Ejemplo n.º 3
0
static void marshall_basetype(Marshall *m)
{
    switch(m->type().element()) {        
    case Smoke::t_bool:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (!value.isBool()) {
                m->item().s_bool = false;
            } else {
                m->item().s_bool = value.toBool();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_bool);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
    
    case Smoke::t_char:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_char = 0;
            } else {
                m->item().s_char = (char) value.toInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_char);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
    
    case Smoke::t_uchar:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_uchar = 0;
            } else {
                m->item().s_uchar = (uchar) value.toUInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_uchar);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
    
    case Smoke::t_short:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_short = 0;
            } else {
                m->item().s_short = (short) value.toInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_short);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_ushort:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_ushort = 0;
            } else {
                m->item().s_ushort = value.toUInt16();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_ushort);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_int:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_int = 0;
            } else {
                m->item().s_int = value.toInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_int);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_uint:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_uint = 0;
            } else {
                m->item().s_uint = value.toUInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_uint);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_long:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_long = 0;
            } else {
                m->item().s_long = (long) value.toInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), (int) m->item().s_long);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_ulong:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_ulong = 0;
            } else {
                m->item().s_ulong = (ulong) value.toUInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), (uint) m->item().s_ulong);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_float:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_float = 0.0;
            } else {
                m->item().s_float = (float) value.toNumber();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_float);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_double:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_double = 0.0;
            } else {
                m->item().s_double = value.toNumber();
            }
            break;
        }
        case Marshall::ToQScriptValue:
            *(m->var()) = QScriptValue(m->engine(), m->item().s_double);
            break;
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_enum:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_enum = 0;
            } else if (value.instanceOf(JSmoke::Global::QtEnum)) {
                m->item().s_enum = value.property("value").toUInt32();
            } else {
                m->item().s_enum = value.toUInt32();
            }
            break;
        }
        case Marshall::ToQScriptValue:
        {
            QScriptValueList args;
            args << (uint) m->item().s_enum << m->type().name();
            *(m->var()) = JSmoke::Global::QtEnum.call(QScriptValue(), args);
            break;
        }
        default:
            m->unsupported();
            break;
        }
        break;
        
    case Smoke::t_class:
        switch(m->action()) {
        case Marshall::FromQScriptValue:
        {
            QScriptValue value = *(m->var());

            if (value.isNull()) {
                m->item().s_class = 0;
                return;
            }
            
            if (value.isDate()) {
                Smoke::ModuleIndex classId = Smoke::findClass(m->smoke()->classes[m->type().classId()].className);
                if (classId == JSmoke::Global::QDateClassId) {
                    m->item().s_class = new QDate(value.toDateTime().date());
                } else if (classId == JSmoke::Global::QDateTimeClassId) {
                     m->item().s_class = new QDateTime(value.toDateTime());
                } else if (classId == JSmoke::Global::QTimeClassId) {
                     m->item().s_class = new QTime(value.toDateTime().time());
                } else {
                    m->item().s_class = 0;
                }
                
                return;
            } else if (value.isRegExp()) {
                m->item().s_class = new QRegExp(value.toRegExp());
                return;
            }
            
            if (!Object::Instance::isSmokeObject(value)) {
                m->item().s_class = 0;
                return;
            }
            
            Object::Instance * instance = Object::Instance::get(value);
            void * ptr = instance->value;
            
            if (!m->cleanup() && m->type().isStack()) {
                ptr = constructCopy(instance);
            }
            
            ptr = instance->classId.smoke->cast(    ptr, 
                                                    instance->classId, 
                                                    Smoke::ModuleIndex(m->smoke(), m->type().classId()) );
            
            m->item().s_class = ptr;
            break;
        }
        
        case Marshall::ToQScriptValue:
        {
            if (m->item().s_voidp == 0) {
                *(m->var()) = m->engine()->nullValue();
                return;
            }
            
            void * ptr = m->item().s_voidp;
            QScriptValue * value = JSmoke::Global::getScriptValue(ptr);
            
            if (value != 0) {
                *(m->var()) = *value;
                return ;
            }
            
            QByteArray className(m->smoke()->classes[m->type().classId()].className);
            QScriptValue obj = Global::wrapInstance(    m->engine(), 
                                                        Smoke::findClass(className), 
                                                        ptr,
                                                        QScriptEngine::QtOwnership );
            
            if (m->type().isConst() && m->type().isRef()) {
                Object::Instance * instance = Object::Instance::get(obj);
                ptr = constructCopy(instance);

                if (ptr != 0) {
                    instance->value = ptr;
                    instance->ownership = QScriptEngine::ScriptOwnership;
                    Global::mapPointer(new QScriptValue(obj), instance, instance->classId);
                }
            }

            *(m->var()) = obj;
            break;
        }
        
        default:
            m->unsupported();
            break;
        }
        break;
        
    default:
        m->unsupported();
        break;
    }
}