コード例 #1
0
void HostedObject::disconnectFromSpace(const SpaceID &spaceID, const ObjectReference& oref)
{
    if (stopped()) {
        HO_LOG(detailed,"Ignoring disconnection request after system stop requested.");
        return;
    }

    SpaceObjectReference sporef(spaceID, oref);
    Mutex::scoped_lock locker(presenceDataMutex);
    PresenceDataMap::iterator where;
    where=mPresenceData.find(sporef);
    if (where!=mPresenceData.end()) {
        // Need to actually send a disconnection request to the space. Note that
        // this occurse *before* getting rid of the other data so callbacks
        // invoked as a result still work.
        mObjectHost->disconnectObject(spaceID,oref);
        delete where->second;
        mPresenceData.erase(where);
        mObjectHost->unregisterHostedObject(sporef, this);
    } else {
        SILOG(cppoh,error,"Attempting to disconnect from space "<<spaceID<<" and object: "<< oref<<" when not connected to it...");
    }
}
コード例 #2
0
void TimerSpeedBenchmark::start() {
    mForceStop = false;

    // Check throughput of timer calls
    Time start_time = Timer::now();

    Time dummy_t = Time::null();
    for(uint32 ii = 0; ii < ITERATIONS && !mForceStop; ii++)
        dummy_t = Timer::now();

    if (mForceStop)
        return;

    Time end_time = Timer::now();
    Duration dur = end_time - start_time;

    SILOG(benchmark,info,
          ITERATIONS << " timer invokations, " << dur << ": "
          << (dur.toMicroseconds()*1000/float(ITERATIONS)) << "ns/call, "
          << float(ITERATIONS)/dur.toSeconds() << " calls/s");

    notifyFinished();
}
コード例 #3
0
ファイル: CassandraStorage.cpp プロジェクト: pathorn/sirikata
void CassandraStorage::StorageAction::execute(const Bucket& bucket, Columns* columns, Keys* eraseKeys, Keys* readKeys, const String& timestamp) {
    switch(type) {
      case Read:
        {
            (*readKeys).push_back(key);
        }
        break;
      case Write:
        {
            Column col = libcassandra::createColumn(key, *value);
            (*columns).push_back(col);
        }
        break;
      case Erase:
        {
            (*eraseKeys).push_back(key);
        }
        break;
      case Error:
        SILOG(cassandra-storage, fatal, "Tried to execute an invalid StorageAction.");
        break;
    };
}
コード例 #4
0
ファイル: Broadcast.cpp プロジェクト: MikeSofaer/sirikata
Broadcast::BroadcastStream *Broadcast::establishBroadcast(const Network::Address&addy, 
                                                          const UUID&name,
                                                          const std::tr1::function<void(BroadcastStream*,
                                                                                        Network::Stream::ConnectionStatus, 
                                                                                        const std::string&reason)>& cb) {
    Broadcast::BroadcastStream * retval=NULL;
    Network::Stream*newBroadcastStream=NULL;

    while(newBroadcastStream==NULL) {
        boost::lock_guard<boost::mutex>lok(*mUniqueLock);
        std::tr1::weak_ptr<Network::Stream>*weak_topLevelStream=&mTopLevelStreams[addy];
        std::tr1::shared_ptr<Network::Stream> topLevelStream;
        if ((topLevelStream=weak_topLevelStream->lock())) {
        }else{
            std::tr1::shared_ptr<Network::Stream> tlstemp(Network::StreamFactory::getSingleton().getDefaultConstructor()(mIOService));
            (topLevelStream=tlstemp)->connect(addy,&Network::Stream::ignoreSubstreamCallback,&Network::Stream::ignoreConnectionStatus,&Network::Stream::ignoreBytesReceived);
            *weak_topLevelStream=tlstemp;
        }
        newBroadcastStream=topLevelStream->clone(std::tr1::bind(&BroadcastStreamCallbacks::setBroadcastStreamCallbacks,
                                                                retval=new BroadcastStream(topLevelStream,NULL),
                                                                cb,
                                                                _1,
                                                                _2));
        if (newBroadcastStream){
            *weak_topLevelStream=topLevelStream;
        }else {
            if (mTopLevelStreams.find(addy)!=mTopLevelStreams.end()) {
                mTopLevelStreams.erase(mTopLevelStreams.find(addy));
            }
            SILOG(broadcast,warning,"Toplevel stream failed to clone for address "<<addy.getHostName()<<':'<<addy.getService());
        }

    }
    initiateHandshake(retval,addy,name);
    return retval;
}
コード例 #5
0
 inline void execute_finished(std::tr1::shared_ptr<RemoteFileMetadata> response, ExecuteFinished cb) {
     mRemoteFileMetadata = response;
     cb();
     SILOG(transfer, detailed, "done MetadataRequest execute_finished");
 }
コード例 #6
0
void HostedObject::handleProximityUpdate(const SpaceObjectReference& spaceobj, const Sirikata::Protocol::Prox::ProximityUpdate& update) {
    HostedObject* self = this;
    SpaceID space = spaceobj.space();

    ProxyManagerPtr proxy_manager = self->getProxyManager(spaceobj.space(),spaceobj.object());
    if (!proxy_manager) {
        HO_LOG(warn,"Hosted Object received a message for a presence without a proxy manager.");
        return;
    }

    for(int32 aidx = 0; aidx < update.addition_size(); aidx++) {
        Sirikata::Protocol::Prox::ObjectAddition addition = update.addition(aidx);
        ProxProtocolLocUpdate add(addition);

        SpaceObjectReference proximateID(spaceobj.space(), add.object());

        TimedMotionVector3f loc(add.locationWithLocalTime(this, spaceobj.space()));

        CONTEXT_OHTRACE(prox,
            spaceobj.object().getAsUUID(),
            //getUUID(),
            addition.object(),
            true,
            loc
        );

        TimedMotionQuaternion orient(add.orientationWithLocalTime(this, spaceobj.space()));
        BoundingSphere3f bnds = add.bounds();
        String mesh = add.meshOrDefault();
        String phy = add.physicsOrDefault();
        bool isAggregate =
          (addition.type() == Sirikata::Protocol::Prox::ObjectAddition::Aggregate) ?
            true : false;

        ProxyObjectPtr proxy_obj = proxy_manager->getProxyObject(proximateID);
        if (!proxy_obj) {
            Transfer::URI meshuri;
            if (addition.has_mesh()) meshuri = Transfer::URI(addition.mesh());


            // FIXME use weak_ptr instead of raw
            uint64 proxyAddSeqNo = add.location_seqno();
            assert( add.location_seqno() == add.orientation_seqno() &&
                 add.location_seqno() == add.bounds_seqno() &&
                add.location_seqno() == add.mesh_seqno() &&
                add.location_seqno() == add.physics_seqno());
            proxy_obj = self->createProxy(proximateID, spaceobj, meshuri, loc, orient, bnds, phy, "",
                                          isAggregate, proxyAddSeqNo);
        }
        else {
            // We need to handle optional values properly -- they
            // shouldn't get overwritten.
            String* mesh_ptr = (addition.has_mesh() ? &mesh : NULL);
            String* phy_ptr = (addition.has_physics() ? &phy : NULL);

            self->processLocationUpdate(space, proxy_obj, false,
                &loc, add.location_seqno(),
                &orient, add.orientation_seqno(),
                &bnds, add.bounds_seqno(),
                mesh_ptr, add.mesh_seqno(),
                phy_ptr, add.physics_seqno()
            );
        }

        // Always mark the object as valid (either revalidated, or just
        // valid for the first time)
        if (proxy_obj) proxy_obj->validate();

        //tells the object script that something that was close has come
        //into view
        if(self->mObjectScript)
            self->mObjectScript->notifyProximate(proxy_obj,spaceobj);
    }

    for(int32 ridx = 0; ridx < update.removal_size(); ridx++) {
        Sirikata::Protocol::Prox::ObjectRemoval removal = update.removal(ridx);

        SpaceObjectReference removed_obj_ref(spaceobj.space(),
            ObjectReference(removal.object()));

        bool permanent = (removal.has_type() && (removal.type() == Sirikata::Protocol::Prox::ObjectRemoval::Permanent));

        if (removed_obj_ref == spaceobj) {
            // We want to ignore removal of ourself -- we should
            // always be in our result set, and we don't want to
            // delete our own proxy.

            SILOG(oh,detailed,"Ignoring self removal from proximity results.");
        }
        else {
            ProxyObjectPtr proxy_obj = proxy_manager->getProxyObject(removed_obj_ref);

            if (proxy_obj) {
                // NOTE: We *don't* reset the proxy object
                // here. Resetting it puts the seqnos back at 0,
                // but if we get an addition while still on this
                // space server, we actually want the old ones to
                // stay in place, in case of unordered prox/loc
                // updates. Resetting only happens when we move
                // across space servers (see handleMigrated).
                proxy_manager->destroyObject(proxy_obj);

                if (self->mObjectScript)
                    self->mObjectScript->notifyProximateGone(proxy_obj,spaceobj);

                proxy_obj->invalidate(permanent);
            }
        }

        CONTEXT_OHTRACE(prox,
            spaceobj.object().getAsUUID(),
            //getUUID(),
            removal.object(),
            false,
            TimedMotionVector3f()
        );
    }

}
コード例 #7
0
ファイル: ObjectFactory.cpp プロジェクト: AsherBond/sirikata
/** Object packs are our own custom format for simple, fixed, object tests. The file format is
 *  a simple binary dump of each objects information:
 *
 *    struct ObjectInformation {
 *        uint64 object_id;
 *        double x;
 *        double y;
 *        double z;
 *        double radius;
 *    };
 *
 *  This gives the minimal information for a static object and allows you to seek directly to any
 *  object in the file, making it easy to split the file across multiple object hosts.
 */
void ObjectFactory::generatePackObjects(const BoundingBox3f& region, const Duration& duration) {
    bool dump_pack = GetOptionValue<bool>(OBJECT_PACK_DUMP);
    if (dump_pack) return; // If we're dumping objects, don't load
                           // from a pack

    Time start(Time::null());

    uint32 nobjects = GetOptionValue<uint32>(OBJECT_PACK_NUM);
    if (nobjects == 0) return;
    String pack_filename = GetOptionValue<String>(OBJECT_PACK);
    assert(!pack_filename.empty());

    String pack_dir = GetOptionValue<String>(OBJECT_PACK_DIR);
    pack_filename = pack_dir + pack_filename;

    FILE* pack_file = fopen(pack_filename.c_str(), "rb");
    if (pack_file == NULL) {
        SILOG(objectfactory,error,"Couldn't open object pack file, not generating any objects.");
        assert(false);
        return;
    }

    // First offset ourselves into the file
    uint32 pack_offset = GetOptionValue<uint32>(OBJECT_PACK_OFFSET);

    uint32 obj_pack_size =
        8 + // objid
        8 + // radius
        8 + // x
        8 + // y
        8 + // z
        0;
    int seek_success = fseek( pack_file, obj_pack_size * pack_offset, SEEK_SET );
    if (seek_success != 0) {
        SILOG(objectfactory,error,"Couldn't seek to appropriate offset in object pack file.");
        fclose(pack_file);
        return;
    }

    for(uint32 i = 0; i < nobjects; i++) {
        ObjectInputs* inputs = new ObjectInputs;

        uint64 pack_objid = 0;
        double x = 0, y = 0, z = 0, rad = 0;
        fread( &pack_objid, sizeof(uint64), 1, pack_file );
        fread( &x, sizeof(double), 1, pack_file );
        fread( &y, sizeof(double), 1, pack_file );
        fread( &z, sizeof(double), 1, pack_file );
        fread( &rad, sizeof(double), 1, pack_file );

        UUID id = pack2UUID(pack_objid);

        Vector3f startpos((float)x, (float)y, (float)z);
        float bounds_radius = (float)rad;
        //SILOG(oh,error,"Preating "<<id.toString()<<" radius "<<bounds_radius);
        inputs->localID = mLocalIDSource++;
        inputs->motion = new StaticMotionPath(start, startpos);
        inputs->bounds = BoundingSphere3f( Vector3f(0, 0, 0), bounds_radius );
        inputs->registerQuery = false;
        inputs->queryAngle = SolidAngle::Max;
        inputs->connectAt = Duration::seconds(0.f);

        inputs->startTimer = Network::IOTimer::create(mContext->ioService);

        mObjectIDs.insert(id);
        mInputs[id] = inputs;
    }

    fclose(pack_file);
}
コード例 #8
0
    /**
     * Process a message that may be meant for the proximity system
     * \returns true if object was deleted
     */
    OpaqueMessageReturnValue internalProcessOpaqueProximityMessage(
                                               const ObjectReference*object,
                                               const RoutableMessageHeader& hdr,
                                               const void *serializedMessageBody,
                                               size_t serializedMessageBodySize,
                                               bool trusted) {
        try {
            RoutableMessage msg(hdr,serializedMessageBody,serializedMessageBodySize);
            MessageBundle sendState=DELIVER_TO_UNKNOWN;
            bool deliverAllMessages=true;
            int len=msg.body().message_size();
            OpaqueMessageReturnValue obj_is_deleted=OBJECT_NOT_DESTROYED;
            bool disconnection=false;
            bool registration=false;
            for (int i=0;i<len;++i) {
                if (trusted||(hdr.has_source_object()&&hdr.source_object()==ObjectReference::spaceServiceID()&&hdr.source_port()==mRegistrationPort)) {
                    if(msg.body().message_names(i)=="DelObj") {
                        disconnection=true;
                        obj_is_deleted=OBJECT_DELETED;
                    }
                    if(msg.body().message_names(i)=="RetObj") {
                        registration=true;
                        Sirikata::Protocol::RetObj ro;
                        ro.ParseFromString(msg.body().message_arguments(i));
                        newObj(ro,msg.body().message_arguments(i).data(),msg.body().message_arguments(i).size());
                    }
                }
                if (!forwardThisName(disconnection,msg.body().message_names(i))) {
                    if (len==1) return obj_is_deleted;
                    deliverAllMessages=false;
                }else {
                    if (msg.body().message_names(i)==proxCallbackName()) {
                        if (sendState==DELIVER_TO_UNKNOWN||sendState==DELIVER_TO_OBJECT)
                            sendState=DELIVER_TO_OBJECT;
                        else 
                            sendState=DELIVER_TO_BOTH;
                    }else{
                        if (sendState==DELIVER_TO_UNKNOWN||sendState==DELIVER_TO_PROX)
                            sendState=DELIVER_TO_PROX;
                        else 
                            sendState=DELIVER_TO_BOTH;
                    }
                }
            }
            if (sendState==DELIVER_TO_UNKNOWN)
                return obj_is_deleted;//no messages considered worth forwarding to the proximity system
            if (sendState==DELIVER_TO_BOTH) {
                SILOG(prox,info,"Message with recipients both proximity and object bundled into the same message: not delivering.");
                return obj_is_deleted;
            }
/* NOT SURE THIS IS NECESSARY -- do these messages already have addresses on them?*/
            DidAlterMessage alteration;
            if (sendState==DELIVER_TO_PROX) 
                alteration=addressMessage(msg,object,NULL);
            else
                alteration=addressMessage(msg,NULL,object);
            if (deliverAllMessages&&sendState==DELIVER_TO_PROX) {
                sendMessage(*object,msg,serializedMessageBody,serializedMessageBodySize);
            } else if (deliverAllMessages&&sendState==DELIVER_TO_OBJECT) {
                deliverMessage(*object,msg,serializedMessageBody,serializedMessageBodySize);
            }else {
                //some messages are not considered worth forwarding to the proximity system or there's a mishmash of destinations
                if (msg.body().message_size()<len) {
                    len=msg.body().message_size();
                }
                RoutableMessage newMsg (msg);
                newMsg.body().clear_message();
                for (int i=0;i<len;++i) {
                    if (forwardThisName(registration||disconnection,msg.body().message_names(i))) {
                        newMsg.body().add_message(msg.body().message_names(i), msg.body().message_arguments(i));
                    }
                }
                if (sendState==DELIVER_TO_OBJECT)
                    deliverMessage(*object,newMsg,NULL,0);
                if (sendState==DELIVER_TO_PROX)
                    sendMessage(*object,newMsg,NULL,0);
                
            }
            return obj_is_deleted;
        }catch(std::invalid_argument&ia) {
            SILOG(proximity,warning,"Could not parse message");
            return OBJECT_NOT_DESTROYED;
        }

    }
コード例 #9
0
///gets called when a complete 24 byte header is actually received: uses the UUID within to match up appropriate sockets
void buildStream(TcpSstHeaderArray *buffer,
                 TCPSocket *socket,
                 std::tr1::shared_ptr<TCPStreamListener::Data> data,
                 const boost::system::error_code &error,
                 std::size_t bytes_transferred)
{
    // Buffer always needs to be cleaned up when we get out of this method
    std::auto_ptr<TcpSstHeaderArray> buffer_ptr(buffer);

    // Sanity check start
    if (error || bytes_transferred < 5 || std::string((const char*)buffer->begin(), 5) != std::string("GET /")) {
        SILOG(tcpsst,warning,"Connection received with truncated header: "<<error);
        delete socket;
        return;
    }

    // Sanity check end: 8 bytes from WebSocket spec after headers, then
    // \r\n\r\n before that.
    std::string buffer_str((const char*)buffer->begin(), bytes_transferred);
    if (buffer_str[ bytes_transferred - 12] != '\r' ||
        buffer_str[ bytes_transferred - 11] != '\n' ||
        buffer_str[ bytes_transferred - 10] != '\r' ||
        buffer_str[ bytes_transferred - 9] != '\n')
    {
        SILOG(tcpsst,warning,"Request doesn't end properly:\n" << buffer_str << "\n");
        delete socket;
        return;
    }

    std::string headers_str = buffer_str.substr(0, bytes_transferred - 10);
    // Parse headers
    UUID context;
    std::map<std::string, std::string> headers;
    std::string::size_type offset = 0;
    while(offset < headers_str.size()) {
        std::string::size_type last_offset = offset;
        offset = headers_str.find("\r\n", offset);
        if (offset == std::string::npos) {
            SILOG(tcpsst,warning,"Error parsing headers.");
            delete socket;
            return;
        }

        std::string line = headers_str.substr(last_offset, offset - last_offset);

        // Special case the initial GET line
        if (line.substr(0, 5) == "GET /") {
            std::string::size_type uuid_end = line.find(' ', 5);
            if (uuid_end == std::string::npos) {
                SILOG(tcpsst,warning,"Error parsing headers: invalid get line.");
                delete socket;
                return;
            }
            std::string uuid_str = line.substr(5, uuid_end - 5);
            try {
                context = UUID(uuid_str,UUID::HumanReadable());
            } catch(...) {
                SILOG(tcpsst,warning,"Error parsing headers: invalid get uuid.");
                delete socket;
                return;
            }

            offset += 2;
            continue;
        }

        std::string::size_type colon = line.find(":");
        if (colon == std::string::npos) {
            SILOG(tcpsst,warning,"Error parsing headers: missing colon.");
            delete socket;
            return;
        }
        std::string head = line.substr(0, colon);
        std::string val = line.substr(colon+2);

        headers[head] = val;

        // Advance to get past the \r\n
        offset += 2;
    }

    if (headers.find("Host") == headers.end() ||
        headers.find("Origin") == headers.end() ||
        headers.find("Sec-WebSocket-Key1") == headers.end() ||
        headers.find("Sec-WebSocket-Key2") == headers.end())
    {
        SILOG(tcpsst,warning,"Connection request didn't specify all required fields.");
        delete socket;
        return;
    }

    std::string host = headers["Host"];
    std::string origin = headers["Origin"];
    std::string protocol = "wssst1";
    if (headers.find("Sec-WebSocket-Protocol") != headers.end())
        protocol = headers["Sec-WebSocket-Protocol"];
    std::string key1 = headers["Sec-WebSocket-Key1"];
    std::string key2 = headers["Sec-WebSocket-Key2"];
    std::string key3 = buffer_str.substr(bytes_transferred - 8);
    assert(key3.size() == 8);

    std::string reply_str = getWebSocketSecReply(key1, key2, key3);

    bool binaryStream=protocol.find("sst")==0;
    bool base64Stream=!binaryStream;
    boost::asio::ip::tcp::no_delay option(data->mNoDelay);
    socket->set_option(option);
    IncompleteStreamMap::iterator where=sIncompleteStreams.find(context);

    unsigned int numConnections=1;

    for (std::string::iterator i=protocol.begin(),ie=protocol.end();i!=ie;++i) {
        if (*i>='0'&&*i<='9') {
            char* endptr=NULL;
            const char *start=protocol.c_str();
            size_t offset=(i-protocol.begin());
            start+=offset;
            numConnections=strtol(start,&endptr,10);
            size_t numberlen=endptr-start;
            if (numConnections>data->mMaxSimultaneousSockets) {
                numConnections=data->mMaxSimultaneousSockets;
                char numcon[256];
                sprintf(numcon,"%d",numConnections);
                protocol=protocol.substr(0,offset)+numcon+protocol.substr(offset+numberlen);
            }
            break;
        }
    }

    if (where==sIncompleteStreams.end()){
        sIncompleteStreams[context].mNumSockets=numConnections;
        where=sIncompleteStreams.find(context);
        assert(where!=sIncompleteStreams.end());
        // Setup a timer to clean up the sockets if we don't complete it in time
        data->strand->post(
            Duration::seconds(10),
            std::tr1::bind(&handleBuildStreamTimeout, context)
        );
    }
    if ((int)numConnections!=where->second.mNumSockets) {
        SILOG(tcpsst,warning,"Single client disagrees on number of connections to establish: "<<numConnections<<" != "<<where->second.mNumSockets);
        sIncompleteStreams.erase(where);
    }else {
        where->second.mSockets.push_back(socket);
        where->second.mWebSocketResponses[socket] = reply_str;
        if (numConnections==(unsigned int)where->second.mSockets.size()) {
            MultiplexedSocketPtr shared_socket(
                MultiplexedSocket::construct<MultiplexedSocket>(data->strand,context,data->cb,base64Stream));
            shared_socket->initFromSockets(where->second.mSockets,data->mSendBufferSize);
            std::string port=shared_socket->getASIOSocketWrapper(0).getLocalEndpoint().getService();
            std::string resource_name='/'+context.toString();
            MultiplexedSocket::sendAllProtocolHeaders(shared_socket,origin,host,port,resource_name,protocol, where->second.mWebSocketResponses);
            sIncompleteStreams.erase(where);


            Stream::StreamID newID=Stream::StreamID(1);
            TCPStream * strm=new TCPStream(shared_socket,newID);

            TCPSetCallbacks setCallbackFunctor(&*shared_socket,strm);
            data->cb(strm,setCallbackFunctor);
            if (setCallbackFunctor.mCallbacks==NULL) {
                SILOG(tcpsst,error,"Client code for stream "<<newID.read()<<" did not set listener on socket");
                shared_socket->closeStream(shared_socket,newID);
            }
        }else{
            sStaleUUIDs.push_back(context);
        }
    }
}
コード例 #10
0
boost::any JSInvokableObjectInt::invoke(std::vector<boost::any> &params)
{
  /* Invoke the invokable version */
    SILOG(js,detailed,"JSInvokableObjectInt::invoke(): invokable_ type is " << typeid(invokable_).name());
  return invokable_->invoke(params);
}
コード例 #11
0
void SingleStreamProximityConnection::streamDisconnected() {
    SILOG(proximity,error,"Lost connection with proximity manager");
}
コード例 #12
0
ファイル: Asio.cpp プロジェクト: danielrh/sirikata
void InternalIOWork::logEvent(const String& evt) {
    if (mName != "")
        SILOG(io,insane,"IOWork event: " << mName << " -> " << evt);
}
コード例 #13
0
Stream::ReceivedResponse MultiplexedSocket::receiveFullChunk(unsigned int whichSocket, Stream::StreamID id,Chunk&newChunk){
    Stream::ReceivedResponse retval = Stream::AcceptedData;
    if (id==Stream::StreamID()) {//control packet
        if(newChunk.size()) {
            unsigned int controlCode=*newChunk.begin();
            switch (controlCode) {
              case TCPStream::TCPStreamCloseStream:
              case TCPStream::TCPStreamAckCloseStream:
                if (newChunk.size()>1) {
                    unsigned int avail_len=newChunk.size()-1;
                    id.unserialize((const uint8*)&(newChunk[1]),avail_len);
                    if (avail_len+1>newChunk.size()) {
                        SILOG(tcpsst,warning,"Control Chunk too short");
                    }
                }
                if (id!=Stream::StreamID()) {
                    std::tr1::unordered_map<Stream::StreamID,unsigned int>::iterator where=mAckedClosingStreams.find(id);
                    if (where!=mAckedClosingStreams.end()){
                        where->second++;
                        int how_much=where->second;
                        if (where->second==mSockets.size()) {
                            mAckedClosingStreams.erase(where);
                            shutDownClosedStream(controlCode,id);
                            if (controlCode==TCPStream::TCPStreamCloseStream) {
                                closeStream(getSharedPtr(),id,TCPStream::TCPStreamAckCloseStream);
                            }
                        }
                    }else{
                        if (mSockets.size()==1) {
                            shutDownClosedStream(controlCode,id);
                            if (controlCode==TCPStream::TCPStreamCloseStream) {
                                closeStream(getSharedPtr(),id,TCPStream::TCPStreamAckCloseStream);
                            }
                        }else {
                            mAckedClosingStreams[id]=1;
                        }
                    }
                }
                break;
              default:
                break;
            }
        }
    }else {
        std::deque<StreamIDCallbackPair> registrations;
        CommitCallbacks(registrations,CONNECTED,false);
        CallbackMap::iterator where=mCallbacks.find(id);
        if (where!=mCallbacks.end()) {
            retval=where->second->mBytesReceivedCallback(newChunk);
        }else if (mOneSidedClosingStreams.find(id)==mOneSidedClosingStreams.end()) {
            //new substream
            TCPStream*newStream=new TCPStream(getSharedPtr(),id);
            TCPSetCallbacks setCallbackFunctor(this,newStream);
            mNewSubstreamCallback(newStream,setCallbackFunctor);
            if (setCallbackFunctor.mCallbacks != NULL) {
                CommitCallbacks(registrations,CONNECTED,false);//make sure bytes are received
                retval=setCallbackFunctor.mCallbacks->mBytesReceivedCallback(newChunk);
            }else {
                closeStream(getSharedPtr(),id);
            }
        }else {
            //IGNORED MESSAGE
        }
    }
    return retval;
}
コード例 #14
0
MonoVWObjectScript::MonoVWObjectScript(Mono::MonoSystem*mono_system, HostedObject*ho, const ObjectScriptManager::Arguments&args):mDomain(mono_system->createDomain()){
    mParent=ho;
    int ignored_args=0;
    String reserved_string_assembly="Assembly";
    String reserved_string_class="Class";
    String reserved_string_namespace="Namespace";
    String reserved_string_function="Function";
    String assembly_name;//="Sirikata.Runtime";
    ObjectScriptManager::Arguments::const_iterator i=args.begin(),j,func_iter;
    if ((i=args.find(reserved_string_assembly))!=args.end()) {
        assembly_name=i->second;
        ++ignored_args;
    }
    mono_system->loadAssembly(assembly_name);
    try {
        Mono::Assembly ass=mDomain.getAssembly(i->second);
        String class_name;//="PythonObject";
        String namespace_name;//="Sirikata.Runtime";
        
        if ((i=args.find(reserved_string_class))!=args.end()) {        
            ++ignored_args;
            class_name=i->second;
        }
        if ((i=args.find(reserved_string_namespace))!=args.end()) {        
            ++ignored_args;
            namespace_name=i->second;
        }
        if ((func_iter=args.find(reserved_string_function))!=args.end()) {        
            ++ignored_args;
        }
        MonoContext::getSingleton().push(MonoContextData());
        MonoContext::getSingleton().setVWObject(ho,mDomain);
        try {
            
            Mono::Class class_type=ass.getClass(namespace_name,class_name);
            Mono::Object exampleString=mDomain.String(String());
            Mono::Array mono_args=Mono::Array(mDomain.Array(exampleString.type(),(args.size()-ignored_args)*2));
            unsigned int mono_count=0;
            
            for (i=args.begin(),j=args.end();i!=j;++i) {
                if (i->first!=reserved_string_assembly&&i->first!=reserved_string_class&&i->first!=reserved_string_namespace&&i->first!=reserved_string_function) {                        
                    mono_args.set(mono_count++,mDomain.String(i->first));
                    mono_args.set(mono_count++,mDomain.String(i->second));
                }
            }
            try {
                if (func_iter==args.end()) {
                    mObject=class_type.instance(mono_args);
                }else {
                    mObject=class_type.send(func_iter->second,mono_args);
                }
            }catch(Mono::Exception&e) {
                SILOG(mono,warning,"Making new object: Cannot locate method "<<(func_iter==args.end()?String("constructor"):func_iter->second) <<" in class "<<namespace_name<<"::"<<class_name<<"with "<<mono_args.length()<<" arguments."<<e);
            }
        } catch (Mono::Exception&e) {
            SILOG(mono,warning,"Making new object: Cannot locate class "<<namespace_name<<"::"<<class_name<<"."<<e);
        }
        MonoContext::getSingleton().pop();
    } catch (Mono::Exception&e) {
        SILOG(mono,warning,"Making new object: Cannot locate assembly "<<i->second<<"."<<e);
        //no assembly could be loaded
    }
}
コード例 #15
0
	inline void execute_finished(std::tr1::shared_ptr<const DenseData> response, ExecuteFinished cb) {
	    SILOG(transfer, detailed, "execute_finished in ChunkRequest called");
        mDenseData = response;
        HttpManager::getSingleton().postCallback(cb);
        SILOG(transfer, detailed, "done ChunkRequest execute_finished");
	}
コード例 #16
0
 inline void notifyCaller(std::tr1::shared_ptr<TransferRequest> from) {
     std::tr1::shared_ptr<ChunkRequest> fromC =
             std::tr1::static_pointer_cast<ChunkRequest, TransferRequest>(from);
     HttpManager::getSingleton().postCallback(std::tr1::bind(mCallback, fromC, fromC->mDenseData));
     SILOG(transfer, detailed, "done ChunkRequest notifyCaller");
 }
コード例 #17
0
void EventManager<T>::temporary_processEventQueue(AbsTime forceCompletionBy) {
	AbsTime startTime = AbsTime::now();
	SILOG(task,insane," >>> Processing events.");

	// swaps to allow people to keep adding new events
	typename EventList::NodeIterator processingList(mUnprocessed);

	// The events are swapped first to guarantee that listeners are at least as up-to-date as events.
	// Events can be delayed, but we cannot allow any lost subscriptions/unsubscriptions.

	{
		typename ListenerRequestList::NodeIterator procListeners(mListenerRequests);

		const ListenerRequest *req;
		while ((req = procListeners.next()) != NULL) {
			if (req->subscription) {
				SILOG(task,debug," >>>\tDoing subscription listener "<< req->listenerId << " for event " << req->eventId << " (" << req->onlyPrimary <<  ").");
				doSubscribeId(*req);
			} else {
				SILOGNOCR(task,debug," >>>\t");
				if (req->notifyListener) {
					SILOGNOCR(task,debug,"Notifying");
				}
				SILOG(task,debug,"UNSUBSCRIBED listener " << req->listenerId << ".");
				doUnsubscribe(req->listenerId, req->notifyListener);
			}
		}
	}

	if (SILOGP(task,insane)){
		SILOG(task,insane,"==== All Event Subscribers for " << (intptr_t)this << " ====");
		typename PrimaryListenerMap::const_iterator priIter =
			mListeners.begin();
		while (priIter != mListeners.end()) {
			SILOG(task,insane,"  ID " << (*priIter).first << ":");
			PartiallyOrderedListenerList *primaryLists =
				&((*priIter).second->first);
			SecondaryListenerMap *secondaryMap =
				&((*priIter).second->second);

			for (int i = 0; i < NUM_EVENTORDER; i++) {
				ListenerList *currentList = &(primaryLists->get(i));
				for (typename ListenerList::const_iterator iter = currentList->begin();
						iter != currentList->end(); ++iter) {
					SILOG(task,insane," \t"
						"[" << (i==MIDDLE?'=':i<MIDDLE?'*':'/') << "] " <<
						(*iter).second);
				}
			}

			typename SecondaryListenerMap::const_iterator secIter;
			secIter = secondaryMap->begin();
			while (secIter != secondaryMap->end()) {
				SILOG(task,insane,"\tSec ID " << (*secIter).first << ":");
				for (int i = 0; i < NUM_EVENTORDER; i++) {
					ListenerList *currentList = &((*secIter).second->get(i));
					for (typename ListenerList::const_iterator iter = currentList->begin();
							iter != currentList->end(); ++iter) {
						SILOG(task,insane," \t\t"
							"[" << (i==MIDDLE?'=':i<MIDDLE?'*':'/') << "] " <<
							(*iter).second);
					}
				}
				++secIter;
			}
			++priIter;
		}
		SILOG(task,insane,"==== ---------------------------------- ====");
	}

	EventPtr *evTemp;
	int numProcessed = 0;

	while ((evTemp = processingList.next())!=NULL) {
		EventPtr ev (*evTemp);
		++numProcessed;

		typename PrimaryListenerMap::iterator priIter =
			mListeners.find(ev->getId().mPriId);
		if (priIter == mListeners.end()) {
			// FIXME: Should this ever happen?
			SILOG(task,warning," >>>\tWARNING: No listeners for type " <<
                  "event type " << ev->getId().mPriId);
			continue;
		}

		PartiallyOrderedListenerList *primaryLists =
			&((*priIter).second->first);
		SecondaryListenerMap *secondaryMap =
			&((*priIter).second->second);

		typename SecondaryListenerMap::iterator secIter;
		secIter = secondaryMap->find(ev->getId().mSecId);

        bool cancel = false;
        EventHistory eventHistory=EVENT_UNHANDLED;
		// Call once per event order.
		for (int i = 0; i < NUM_EVENTORDER && cancel == false; i++) {
			SILOG(task,debug," >>>\tFiring " << ev << ": " << ev->getId() <<
                  " [order " << i << "]");
			ListenerList *currentList = &(primaryLists->get(i));
			if (!currentList->empty())
				eventHistory=EVENT_HANDLED;
			if (callAllListeners(ev, currentList, forceCompletionBy)) {
				cancel = cancel || true;
			}

			if (secIter != secondaryMap->end() &&
					!(*secIter).second->get(i).empty()) {
				currentList = &((*secIter).second->get(i));
				if (!currentList->empty())
					eventHistory=EVENT_HANDLED;

				if (callAllListeners(ev, currentList, forceCompletionBy)) {
					cancel = cancel || true;
				}
				// all listeners may have returned false.
				// cleanUp(secondaryMap, secIter);
				// secIter = secondaryMap->find(ev->getId().mSecId);
			}

			if (cancel) {
				SILOG(task,debug," >>>\tCancelling " << ev->getId());
			}
		}
		if (secIter != secondaryMap->end()) {
			cleanUp(secondaryMap, secIter);
		}

        if (cancel) eventHistory=EVENT_CANCELED;
        (*ev)(eventHistory);
		SILOG(task,debug," >>>\tFinished " << ev->getId());
	}

	if (mEventCV) {
		mPendingEvents -= numProcessed;
	}

	AbsTime finishTime = AbsTime::now();
	SILOG(task,insane, "**** Done processing events this round. " <<
          "Took " << (finishTime-startTime).toSeconds() <<
		" seconds.");
}
コード例 #18
0
ファイル: Paths.cpp プロジェクト: SinSiXX/sirikata
String Get(Key key) {
    switch(key) {

      case FILE_EXE:
          {
#if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_MAC
              // Executable path can have relative references ("..") depending on
              // how the app was launched.
              uint32_t executable_length = 0;
              _NSGetExecutablePath(NULL, &executable_length);
              std::string executable_path(executable_length, '\0');
              char* executable_path_c = (char*)executable_path.c_str();
              int rv = _NSGetExecutablePath(executable_path_c, &executable_length);
              assert(rv == 0);
              if ((rv != 0) || (executable_path.empty()))
                  return "";
              // _NSGetExecutablePath will return whatever gets execed, so if
              // the command line is ./foo, you'll get the '.'. We use the
              // aggressive mode here to handle '..' parts that could interfere
              // with finding other paths that start from FILE_EXE.
              return canonicalize(executable_path, true);
#elif SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_LINUX
              // boost::filesystem can't chase symlinks, do it manually
              const char* selfExe = "/proc/self/exe";

              char bin_dir[MAX_PATH + 1];
              int bin_dir_size = readlink(selfExe, bin_dir, MAX_PATH);
              if (bin_dir_size < 0 || bin_dir_size > MAX_PATH) {
                  SILOG(core,fatal,"Couldn't read self symlink to setup dynamic loading paths.");
                  return "";
              }
              bin_dir[bin_dir_size] = 0;
              return String(bin_dir, bin_dir_size);
#elif SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
              char system_buffer[MAX_PATH];
              system_buffer[0] = 0;
              GetModuleFileName(NULL, system_buffer, MAX_PATH);
              return String(system_buffer);
#else
              return "";
#endif
          }
          break;

      case DIR_EXE:
          {
              String exe_file = Get(FILE_EXE);
              if (exe_file.empty()) return "";
              boost::filesystem::path exe_file_path(exe_file);
              return exe_file_path.parent_path().string();
          }
          break;

      case DIR_EXE_BUNDLE:
          {
#if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS || SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_LINUX
              // Windows and Linux don't have bundles
              return Get(DIR_EXE);
#elif SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_MAC
              // On mac we need to detect that we're in a .app. We assume this
              // only applies if the binaries are in the standard location,
              // i.e. foo.app/Contents/MacOS/bar_binary
              String exe_dir = Get(DIR_EXE);
              boost::filesystem::path exe_dir_path(exe_dir);
              // Work our way back up verifying the path names, finally
              // returning if we actually find the .app.
              if (exe_dir_path.has_filename() && exe_dir_path.filename() == "MacOS") {
                  exe_dir_path = exe_dir_path.parent_path();
                  if (exe_dir_path.has_filename() && exe_dir_path.filename() == "Contents") {
                      exe_dir_path = exe_dir_path.parent_path();
                      if (exe_dir_path.has_filename()) {
                          String app_dir_name = exe_dir_path.filename();
                          if (app_dir_name.substr(app_dir_name.size()-4, 4) == ".app")
                              return exe_dir_path.parent_path().string();
                      }
                  }
              }
              // Otherwise dump the original
              return exe_dir;
#endif
          }
          break;

      case DIR_CURRENT:
          {
#if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_MAC || SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_LINUX
              char system_buffer[MAX_PATH] = "";
              if (!getcwd(system_buffer, sizeof(system_buffer))) {
                  return "";
              }

              return String(system_buffer);
#elif SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
              char system_buffer[MAX_PATH];
              system_buffer[0] = 0;
              DWORD len = ::GetCurrentDirectory(MAX_PATH, system_buffer);
              if (len == 0 || len > MAX_PATH)
                  return "";
              return String(system_buffer);
#else
              return ".";
#endif
          }
          break;

      case DIR_USER:
          {
#if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_LINUX || SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_MAC
              uid_t uid = getuid();
              passwd* pw = getpwuid(uid);
              if (pw != NULL && pw->pw_dir != NULL) {
                  boost::filesystem::path homedir(pw->pw_dir);
                  if (boost::filesystem::exists(homedir) && boost::filesystem::is_directory(homedir))
                      return homedir.string();
              }
#elif SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
              char system_buffer[MAX_PATH];
              system_buffer[0] = 0;
              if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, system_buffer)))
                  return "";
              std::string appdata_str(system_buffer);
              boost::filesystem::path user_appdata(appdata_str);
              user_appdata /= "Sirikata";
              if (!boost::filesystem::exists(user_appdata))
                  boost::filesystem::create_directory(user_appdata);
              if (boost::filesystem::exists(user_appdata) && boost::filesystem::is_directory(user_appdata))
                  return user_appdata.string();
#endif
              // Last resort (and default for unknown platform) is to try to use
              // the current directory
              return ".";
          }
          break;

      case DIR_USER_HIDDEN:
          {
#if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
              // On windows there's no difference from the user-specific data directory since that's already hidden.
              return Get(DIR_USER);
#else
              // We just compute this as an offset from the user directory
              boost::filesystem::path user_dir(Get(DIR_USER));
              user_dir /= ".sirikata";
              if (!boost::filesystem::exists(user_dir))
                  boost::filesystem::create_directory(user_dir);
              if (boost::filesystem::exists(user_dir) && boost::filesystem::is_directory(user_dir))
                  return user_dir.string();
#endif
              return ".";
          }

      case DIR_TEMP:
          {
#if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_LINUX || SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_MAC
              // On Mac and Linux we try to work under tmp using our own directory
              boost::filesystem::path tmp_path("/tmp");
              if (boost::filesystem::exists(tmp_path) && boost::filesystem::is_directory(tmp_path)) {
                  tmp_path /= "sirikata";
                  // If it doesn't exist, try creating it
                  if (!boost::filesystem::exists(tmp_path))
                      boost::filesystem::create_directory(tmp_path);
                  if (boost::filesystem::exists(tmp_path) && boost::filesystem::is_directory(tmp_path))
                      return tmp_path.string();
              }
#elif SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
              // Windows doesn't seem to suggest a good location for this, so we
              // put it under the app data directory in its own temp directory
              boost::filesystem::path sirikata_temp_dir =
                  boost::filesystem::path(Get(DIR_USER_HIDDEN)) / "temp";
              if (!boost::filesystem::exists(sirikata_temp_dir))
                  boost::filesystem::create_directory(sirikata_temp_dir);
              if (boost::filesystem::exists(sirikata_temp_dir) && boost::filesystem::is_directory(sirikata_temp_dir))
                  return sirikata_temp_dir.string();
#endif
              // Last resort (and default for unknown platform) is to try to use
              // the current directory
              return ".";
          }
          break;

      case DIR_SYSTEM_CONFIG:
          {
#if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_LINUX || SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_MAC
              // This is sirikata specific, so we're looking for more
              // than just /etc.
              if (boost::filesystem::exists("/etc") && boost::filesystem::is_directory("/etc") &&
                  boost::filesystem::exists("/etc/sirikata") && boost::filesystem::is_directory("/etc/sirikata"))
                  return "/etc/sirikata";
              return "";
#else
              // Other platforms don't have an equivalent?
              return "";
#endif
          }
          break;

      case RESOURCE:
          {
              SILOG(core,fatal,"Can't request RESOURCE without specifiying an in-tree path and path to resource.");
              assert(key != RESOURCE);
              return "";
          }
          break;

      default:
        return "";
    }
}
コード例 #19
0
void MeerkatChunkHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response,
        HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error,
        const URI& uri, std::tr1::shared_ptr<Chunk> chunk,
        bool chunkReq, ChunkCallback callback) {

    std::tr1::shared_ptr<DenseData> bad;
    std::string reqType = "file request";
    if(chunkReq) reqType = "chunk request";

    if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) {
        SILOG(transfer, error, "Request parsing failed during an HTTP " << reqType << " (" << uri << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) {
        SILOG(transfer, error, "Response parsing failed during an HTTP " << reqType << " (" << uri << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::BOOST_ERROR) {
        SILOG(transfer, error, "A boost error happened during an HTTP " << reqType << ". Boost error = " << boost_error.message() << " (" << uri << ")");
        callback(bad);
        return;
    } else if (error != HttpManager::SUCCESS) {
        SILOG(transfer, error, "An unknown error happened during an HTTP " << reqType << " (" << uri << ")");
        callback(bad);
        return;
    }

    if (response->getHeaders().size() == 0) {
        SILOG(transfer, error, "There were no headers returned during an HTTP " << reqType << " (" << uri << ")");
        callback(bad);
        return;
    }

    HttpManager::Headers::const_iterator it;
    it = response->getHeaders().find("Content-Length");
    if (it == response->getHeaders().end()) {
        SILOG(transfer, error, "Content-Length header was not present when it should be during an HTTP " << reqType << " (" << uri << ")");
        callback(bad);
        return;
    }

    if (response->getStatusCode() != 200) {
        SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP " << reqType << " (" << uri << ")");
        callback(bad);
        return;
    }

    if (!response->getData()) {
        SILOG(transfer, error, "Body not present during an HTTP " << reqType << " (" << uri << ")");
        callback(bad);
        return;
    }

    it = response->getHeaders().find("Content-Range");
    if (chunkReq && it == response->getHeaders().end()) {
        SILOG(transfer, error, "Expected Content-Range header not present during an HTTP " << reqType << " (" << uri << ")");
        callback(bad);
        return;
    } else if (chunkReq) {
        std::string range_str = it->second;
        bool range_parsed = false;

        if (range_str.substr(0,6) == "bytes ") {
            range_str = range_str.substr(6);
            size_type dashPos = range_str.find('-');
            if (dashPos != std::string::npos) {
                range_str.replace(dashPos, 1, " ");

                //total file size is optional
                size_type slashPos = range_str.find('/');
                if (slashPos != std::string::npos) {
                    range_str.replace(slashPos, 1, " ");
                }

                std::istringstream instream(range_str);
                uint64 range_start;
                uint64 range_end;
                instream >> range_start;
                instream >> range_end;

                if (range_start == chunk->getRange().startbyte() &&
                        range_end == chunk->getRange().endbyte() &&
                        response->getData()->length() == chunk->getRange().length()) {
                    range_parsed = true;
                }
            }
        }
コード例 #20
0
ファイル: TimeSync.hpp プロジェクト: MikeSofaer/sirikata
 static void defaultCallback(const Duration&offset){
     SILOG(objecthost,debug,"New offset is "<<offset);
 }
コード例 #21
0
void MeerkatNameHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response,
        HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error,
        std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {

    std::tr1::shared_ptr<RemoteFileMetadata> bad;

    if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) {
        SILOG(transfer, error, "Request parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) {
        SILOG(transfer, error, "Response parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::BOOST_ERROR) {
        SILOG(transfer, error, "A boost error happened during an HTTP name lookup (" << request->getURI() << "). Boost error = " << boost_error.message());
        callback(bad);
        return;
    } else if (error != HttpManager::SUCCESS) {
        SILOG(transfer, error, "An unknown error happened during an HTTP name lookup. (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getHeaders().size() == 0) {
        SILOG(transfer, error, "There were no headers returned during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    HttpManager::Headers::const_iterator it;
    it = response->getHeaders().find("Content-Length");
    if (it != response->getHeaders().end()) {
        SILOG(transfer, error, "Content-Length header was present when it shouldn't be during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getStatusCode() != 200) {
        SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    it = response->getHeaders().find("File-Size");
    if (it == response->getHeaders().end()) {
        SILOG(transfer, error, "Expected File-Size header not present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }
    std::string file_size_str = it->second;

    it = response->getHeaders().find("Hash");
    if (it == response->getHeaders().end()) {
        SILOG(transfer, error, "Expected Hash header not present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }
    std::string hash = it->second;

    if (response->getData()) {
        SILOG(transfer, error, "Body present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    Fingerprint fp;
    try {
        fp = Fingerprint::convertFromHex(hash);
    } catch(std::invalid_argument e) {
        SILOG(transfer, error, "Hash header didn't contain a valid Fingerprint string (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    std::istringstream istream(file_size_str);
    uint64 file_size;
    istream >> file_size;
    std::ostringstream ostream;
    ostream << file_size;
    if(ostream.str() != file_size_str) {
        SILOG(transfer, error, "Error converting File-Size header string to integer (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    //Just treat everything as a single chunk for now
    Range whole(0, file_size, LENGTH, true);
    Chunk chunk(fp, whole);
    ChunkList chunkList;
    chunkList.push_back(chunk);

    std::tr1::shared_ptr<RemoteFileMetadata> met(new RemoteFileMetadata(fp, request->getURI(),
            file_size, chunkList, response->getRawHeaders()));

    callback(met);
    SILOG(transfer, detailed, "done http name handler request_finished");
}
コード例 #22
0
 void operationCompleted (Ogre::BackgroundProcessTicket)
 {
     SILOG(resource,insane, "Skeleton Load Task opComplete(), waited " << mName);
     signalCompletion();
 }
コード例 #23
0
ファイル: Poller.cpp プロジェクト: AsherBond/sirikata
Poller::~Poller() {
#if SIRIKATA_DEBUG
    if (mPollerRunCount > 0)
        SILOG(poller, error, "Poller is being destroyed with mismatching start/stop calls: " << (mCBTag ? mCBTag : "(unknown)"));
#endif
}
コード例 #24
0
ファイル: ObjectFactory.cpp プロジェクト: AsherBond/sirikata
void ObjectFactory::generateStaticTraceObjects(const BoundingBox3f& region, const Duration& duration) {
    Time start(Time::null());

    uint32 nobjects = GetOptionValue<uint32>(OBJECT_SL_NUM);
    if (nobjects == 0) return;
    String pack_filename = GetOptionValue<String>(OBJECT_SL_FILE);
    assert(!pack_filename.empty());
    String pack_dir = GetOptionValue<String>(OBJECT_PACK_DIR);
    pack_filename = pack_dir + pack_filename;

    Vector3f sim_center = GetOptionValue<Vector3f>(OBJECT_SL_CENTER);

    // First, load in all the objects.
    FILE* pack_file = fopen(pack_filename.c_str(), "rb");
    if (pack_file == NULL) {
        SILOG(objectfactory,error,"Couldn't open object pack file, not generating any objects.");
        assert(false);
        return;
    }

    TraceObjectMap trace_objects;
    // parse each line: uuid x y z t rad
    SLEntry ent;
    char uuid[256];
    while( !feof(pack_file) && fscanf(pack_file, "%s %f %f %f %d %f", uuid, &ent.pos.x, &ent.pos.y, &ent.pos.z, &ent.t, &ent.rad) ) {
        ent.uuid = UUID(std::string(uuid), UUID::HumanReadable());
        //SILOG(oh,error,"Preating "<<ent.uuid.toString()<<" radius "<<ent.rad);
        TraceObjectMap::iterator obj_it = trace_objects.find(ent.uuid);
        if (obj_it == trace_objects.end()) {
            trace_objects[ent.uuid] = ObjectUpdateList();
            obj_it = trace_objects.find(ent.uuid);
        }
        obj_it->second[ent.t] = ent;
    }
    fclose(pack_file);

    // Now get a version sorted by distance from
    typedef std::set<ObjectUpdateList, SortObjectUpdateListByDist> ObjectsByDistanceList;
    ObjectsByDistanceList objs_by_dist = ObjectsByDistanceList( SortObjectUpdateListByDist(sim_center) );
    for(TraceObjectMap::iterator obj_it = trace_objects.begin(); obj_it != trace_objects.end(); obj_it++)
        objs_by_dist.insert(obj_it->second);

    // Finally, for the number of objects requested, insert the data
    ObjectsByDistanceList::iterator obj_it = objs_by_dist.begin();
    for(uint32 i = 0; i < nobjects; i++, obj_it++) {
        ObjectInputs* inputs = new ObjectInputs;
        SLEntry first = (obj_it->begin())->second;

        inputs->localID = mLocalIDSource++;
        inputs->motion = new StaticMotionPath(Time::microseconds(first.t*1000), first.pos);
        inputs->bounds = BoundingSphere3f( Vector3f(0, 0, 0), first.rad );
        inputs->registerQuery = false;
        inputs->queryAngle = SolidAngle::Max;
        inputs->connectAt = Duration::seconds(0.f);

        inputs->startTimer = Network::IOTimer::create(mContext->ioService);

        mObjectIDs.insert(first.uuid);
        mInputs[first.uuid] = inputs;
    }
}
コード例 #25
0
void AssetDownloadTask::handleAssetParsed(Mesh::VisualPtr vis) {
    mAsset = vis;

    if (!vis) {
        SILOG(ogre,error,"Failed to parse mesh " << mAssetURI.toString());
        mCB();
        return;
    }

    // Now we need to handle downloads for each type of Visual.
    MeshdataPtr md( std::tr1::dynamic_pointer_cast<Meshdata>(vis) );
    if (md) {
        // This is a sanity check. There's no way Ogre can reasonably handle meshes
        // that require a ton of draw calls. Estimate them here and if its too high,
        // destroy the data and invoke the callback to make it look like failure.
        {
            // Draw calls =
            //   Number of instances * number of primitives in instance
            uint32 draw_calls = 0;
            Meshdata::GeometryInstanceIterator geoinst_it = md->getGeometryInstanceIterator();
            uint32 geoinst_idx;
            Matrix4x4f pos_xform;
            while( geoinst_it.next(&geoinst_idx, &pos_xform) )
                draw_calls += md->geometry[ md->instances[geoinst_idx].geometryIndex ].primitives.size();

            // Arbitrary number, but probably more than we should even allow given
            // that there are probably hundreds or thousands of other objects
            if (draw_calls > 500) {
                SILOG(ogre,error,"Excessively complicated mesh: " << mAssetURI.toString() << " has " << draw_calls << " draw calls. Ignoring this mesh.");
                mAsset = Mesh::VisualPtr();
                mCB();
                return;
            }
        }
        // Another sanity check: if we have an excessive number of textures,
        // we're probably going to hit some memory constraints
        {
            // Complete arbitrary number
            if (md->textures.size() > 100) {
                SILOG(ogre,error, "Mesh with excessive number of textures: " << mAssetURI.toString() << " has " << md->textures.size() << " textures. Ignoring this mesh.");
                mAsset = Mesh::VisualPtr();
                mCB();
                return;
            }
        }

        // Special case for no dependent downloads
        if (md->textures.size() == 0) {
            mCB();
            return;
        }

        for(TextureList::const_iterator it = md->textures.begin(); it != md->textures.end(); it++) {
            const std::string& texName = *it;
            Transfer::URI texURI( getURL(mAssetURI, texName) );

            ProgressiveMipmapMap::const_iterator findProgTex;
            if (md->progressiveData) {
                findProgTex = md->progressiveData->mipmaps.find(texName);
            }

            if (md->progressiveData && findProgTex != md->progressiveData->mipmaps.end()) {
                const ProgressiveMipmaps& progMipmaps = findProgTex->second.mipmaps;
                uint32 mipmapLevel = 0;
                for ( ; mipmapLevel < progMipmaps.size(); mipmapLevel++) {
                    if (progMipmaps.find(mipmapLevel)->second.width >= 128 || progMipmaps.find(mipmapLevel)->second.height >= 128) {
                        break;
                    }
                }
                uint32 offset = progMipmaps.find(mipmapLevel)->second.offset;
                uint32 length = progMipmaps.find(mipmapLevel)->second.length;
                Transfer::Fingerprint hash = findProgTex->second.archiveHash;
                addDependentDownload(texURI, Transfer::Chunk(hash, Transfer::Range(offset, length, Transfer::LENGTH)));
            } else {
                addDependentDownload(texURI);
            }
        }

        startDependentDownloads();

        return;
    }

    BillboardPtr bboard( std::tr1::dynamic_pointer_cast<Billboard>(vis) );
    if (bboard) {
        // For billboards, we have to download at least the image to display on
        // it
        Transfer::URI texURI( getURL(mAssetURI, bboard->image) );
        addDependentDownload(texURI);
        startDependentDownloads();
        return;
    }

    // If we've gotten here, then we haven't handled the specific type of visual
    // and we need to issue a warning and callback.
    SILOG(ogre, error, "Tried to use AssetDownloadTask for a visual type it doesn't handle (" << vis->type() << "). Not downloading dependent resources.");
    mCB();
}