gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r11602: Don't block while loading ch


From: Sandro Santilli
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11602: Don't block while loading chunks (of XML and variables for example) from network. Fixes annoying stuttering during potlatch (OSM) use.
Date: Thu, 05 Nov 2009 21:46:48 +0100
User-agent: Bazaar (1.16.1)

------------------------------------------------------------
revno: 11602
committer: Sandro Santilli <address@hidden>
branch nick: trunk
timestamp: Thu 2009-11-05 21:46:48 +0100
message:
  Don't block while loading chunks (of XML and variables for example) from 
network. Fixes annoying stuttering during potlatch (OSM) use.
modified:
  libcore/asobj/LoadableObject.cpp
  libcore/movie_root.cpp
  libcore/movie_root.h
=== modified file 'libcore/asobj/LoadableObject.cpp'
--- a/libcore/asobj/LoadableObject.cpp  2009-10-23 10:34:19 +0000
+++ b/libcore/asobj/LoadableObject.cpp  2009-11-05 20:46:48 +0000
@@ -75,11 +75,13 @@
     vm.registerNative(loadableobject_decode, 301, 3);
 }
 
+// TODO: make a member of movie_root::LoadCallback
 bool
 processLoad(movie_root::LoadCallbacks::value_type& v)
 {
-    IOChannel* lt = v.first.get();
-    as_object* obj = v.second;
+    IOChannel* lt = v.stream.get();
+    as_object* obj = v.obj;
+    SimpleBuffer& buf = v.buf;
 
     if (!lt) {
         obj->callMethod(NSV::PROP_ON_DATA, as_value());
@@ -91,32 +93,63 @@
     // bytes, or if the whole input is not read at the first attempt.
     // It seems unlikely that onData would be called with two half-replies
     const size_t chunk = 65535;
+
+    // Allocate chunksize + terminating NULL
+    // TODO only do on first call!
+    buf.reserve(chunk+1);
         
-    boost::scoped_array<char> buf(new char[chunk + 1]);
-    size_t actuallyRead = lt->read(buf.get(), chunk);
-
-    if (!actuallyRead && lt->eof()) {
-        obj->callMethod(NSV::PROP_ON_DATA, as_value());
-        return true;
-    }
-
-    // Do this before the BOM is stripped or actuallyRead will change.
+    size_t actuallyRead = lt->readNonBlocking(buf.data()+buf.size(),
+                                              chunk-buf.size());
+
     string_table& st = getStringTable(*obj);
-    obj->set_member(st.find("_bytesLoaded"), actuallyRead);
-    obj->set_member(st.find("_bytesTotal"), lt->size());
+
+    if ( actuallyRead )
+    {
+        buf.resize(buf.size()+actuallyRead);
+
+        // TODO: use namedString
+        obj->set_member(st.find("_bytesLoaded"), buf.size());
+        // TODO: do this only on first call ?
+        obj->set_member(st.find("_bytesTotal"), lt->size());
+
+        log_debug("LoadableObject Loaded %d bytes, reaching %d total",
+            actuallyRead, buf.size());
+    }
+
+    // We haven't finished if ! EOF and we didn't fill chunk 
+    if ( buf.size() < chunk && ! lt->eof() )
+    {
+        return false;
+    }
+
+
+    log_debug("LoadableObject reached chunksize or EOF (%d), proceeding",
+                buf.size());
+
+    // Terminate the string
+    buf.appendByte('\0');
+
+    log_debug("LoadableObject: after append('0') size got to %d",
+                buf.size());
     
-    buf[actuallyRead] = '\0';
 
     // Strip BOM, if any.
     // See http://savannah.gnu.org/bugs/?19915
+    // TODO: do this *only* on first chunk!!
     utf8::TextEncoding encoding;
-    // NOTE: the call below will possibly change 'xmlsize' parameter
-    char* bufptr = utf8::stripBOM(buf.get(), actuallyRead, encoding);
+    // NOTE: the call below will possibly change 'size' parameter
+    size_t size = buf.size();
+    char* bufptr = utf8::stripBOM((char*)buf.data(), size, encoding);
     if (encoding != utf8::encUTF8 && encoding != utf8::encUNSPECIFIED) {
-        log_unimpl("%s to utf8 conversion in LoadVars input parsing", 
+        log_unimpl("%s to utf8 conversion in LoadableObject input parsing", 
                 utf8::textEncodingName(encoding));
     }
+
     as_value dataVal(bufptr); 
+
+    // Clear the buffer for next iteration.
+    // Data should have been copied to dataVal by now.
+    buf.resize(0);
     
     obj->callMethod(NSV::PROP_ON_DATA, dataVal);
 

=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp    2009-11-04 20:01:38 +0000
+++ b/libcore/movie_root.cpp    2009-11-05 20:46:48 +0000
@@ -1686,7 +1686,7 @@
 movie_root::addLoadableObject(as_object* obj, std::auto_ptr<IOChannel> str)
 {
     boost::shared_ptr<IOChannel> io(str.release());
-    _loadCallbacks.push_back(std::make_pair(io, obj));
+    _loadCallbacks.push_back(LoadCallback(io, obj));
 }
 
 void
@@ -1867,7 +1867,7 @@
 
     for (LoadCallbacks::const_iterator i = _loadCallbacks.begin(),
             e = _loadCallbacks.end(); i != e; ++i) {
-        i->second->setReachable();
+        i->obj->setReachable();
     }
 
     // Mark resources reachable by queued action code

=== modified file 'libcore/movie_root.h'
--- a/libcore/movie_root.h      2009-10-26 07:14:13 +0000
+++ b/libcore/movie_root.h      2009-11-05 20:46:48 +0000
@@ -80,6 +80,7 @@
 #include "RunResources.h" // for initialization
 #include "gnash.h" // Quality
 #include "MovieClip.h"
+#include "SimpleBuffer.h" // for LoadCallback
 
 #ifdef USE_SWFTREE
 # include "tree.hh"
@@ -145,7 +146,16 @@
 
 public:
 
-    typedef std::pair<boost::shared_ptr<IOChannel>, as_object*> LoadCallback;
+    struct LoadCallback {
+        boost::shared_ptr<IOChannel> stream;
+        as_object* obj;
+        SimpleBuffer buf;
+        LoadCallback(boost::shared_ptr<IOChannel> s, as_object* o)
+            : stream(s), obj(o) {}
+    };
+        
+    //typedef std::pair<boost::shared_ptr<IOChannel>, as_object*> LoadCallback;
+        
     typedef std::list<LoadCallback> LoadCallbacks;
 
     /// Default constructor


reply via email to

[Prev in Thread] Current Thread [Next in Thread]