Closed niemeyer closed 9 years ago
From a usage point of view I would prefer a method like addImageProvider
, but for resources. This means that the actual loading of the resources is up to the developer. It could be from disk, http, or appended with go.rice or other resource bundling tools for Go.
That's how it will end up. The points above are simply about how to implement that interface internally.
Did some more reading in the Qt docs.
The QAbstractFileEngine class provides an abstraction for accessing the filesystem.
The QDir, QFile, and QFileInfo classes all make use of a QAbstractFileEngine internally. If you create your own QAbstractFileEngine subclass (and register it with Qt by creating a QAbstractFileEngineHandler subclass), your file engine will be used when the path is one that your file engine handles.
http://qt-project.org/doc/qt-4.8/qabstractfileengine.html
The QAbstractFileEngineHandler class provides a way to register custom file engines with your application.
QAbstractFileEngineHandler is a factory for creating QAbstractFileEngine objects (file engines), which are used internally by QFile, QFileInfo, and QDir when working with files and directories. When you open a file, Qt chooses a suitable file engine by passing the file name from QFile or QDir through an internal list of registered file engine handlers. The first handler to recognize the file name is used to create the engine. Qt provides internal file engines for working with regular files and resources, but you can also register your own QAbstractFileEngine subclasses.
http://qt-project.org/doc/qt-4.8/qabstractfileenginehandler.html
It looks like this is a better method to add this feature. I think we can implement a QAbstractFileEngineHandler
subclass which calls a go function type ResourceProvider func(path string) Resource
which is registered with qml.RegisterResourceProvider(ResourceProvider)
.
ResourceProvider
could return a nil Resource
(at which point the next QFileEngineHandler is tried by Qt).
Resource would look something like type Resource interface { Read(), Seek(), etc. }
.
I think we could register one QAbstractFileEngineHandler
and iterate over the registered ResourceProvider
's within go-qml. Or register a new QAbstractFileEngineHandler
for each ResourceProvider
that is registered. In the first case we could add some path prefix selector, like ImageProvider's providerId
From http://qt-project.org/doc/qt-5/sourcebreaks.html
QFSFileEngine, QAbstractFileEngine, QAbstractFileEngineIterator, and QAbstractFileEngineHandler are no longer public. We recommend you to avoid using these classes as there is no compatibility promise.
Oops... That kinda sucks :-1: Why would they have done that? There is no replacement for this I take.. So really the only way to register resources is with the rcc registration hack? This means that there is no way to let Qt request for resources right? I couldn't find too much about that, but to me it still looks like it will only let you register resources (including the binary blob) before they are used. So there's no way to register something like a ResourceProvider..?
Also, the registerResourceData
used by rcc generated code isn't in a .h file, so is there a compatibility promise on that?
Do you mean qRegisterResourceData
? That's not in a .h
but is depended upon by public code generated by the rcc tool. If they change that, every binary built that uses rcc and linked against qt is immediately broken.
Looks great @niemeyer I've learned a lot about how it works by reading the code. Thanks!
Some references:
The qml package may leverage the public API behind this logic to load the resource from in-memory data:
That's the definition of these macros, from qglobal.h:
These functions are automatically built by the rcc tool. At their bottom, logic similar to the following is used to actually do the registration at runtime:
This function is defined in qtbase/src/corelib/io/qresource.cpp and is exported, but is not declared in any header. It's safe to do a local declaration and use it, though, because public code does the same and depends on it to work.