-
Notifications
You must be signed in to change notification settings - Fork 997
Conversation
Just curious: how do you use such API now? |
For example, a File subclass that uses PhysFS as its backend to read from an in-memory archive. Then, a ResourceCache subclass that overloads GetFile in order to use that new File subclass when loading resources. Finally, functionality that allows derived subsystems to be registered to the context using a base class's type so that existing code that calls |
I still don't see how it would work. Most of the subsystems are registered by the Engine class in its constructor. And it is done in a "hard-wired" fashion. If you would have new subsystem then no problem as it can be registered later elsewhere, but if you have a subclass of existing subsystems then how do you plan to inhibit Engine class from registering the original in the first place? Also, I also cannot see why it is the ResourceCache being the one need to be subclass. Without looking at the code more closely, my intuition says it should be the FileSystem subclass. |
That the subsystems are registered in the Engine constructor I was aware, but for the purpose of keeping the changes minimal, I did not want to modify more code than necessary. For my purposes, I can either forgo using Engine at all and register subsystems myself, or I can overwrite the existing subsystem registration for ResourceCache after Engine construction. I had put some thought into how to go about this, and I wanted to keep the modifications minimal while not affecting all filesystem access, as it's used for stuff like logging and shader caching.... However, I don't have the understanding of Urho3D's design philosophy that you and other senior contributors do, so any advice towards achieving my goal of loosening the restriction of resource loading to the filesystem would be appreciated! I'd like to contribute the code to accomplish it without compromising the quality of the codebase. |
If you break API, it become harder to use the library. |
Thanks for the feedback, I appreciate it.
You're right; I do consider breaking API to be the greater evil. I definitely would not want to make a contribution that breaks anyone's existing Urho projects. To that end, here is another solution that I had thought of that would be a bit more involved. Since
If neither of these options is acceptable, I can withdraw the pull request until a possible solution appears -- not breaking API and/or people's existing code is too important to me. Till now I've just been using a modified Urho codebase in my projects but I'd like to work with a clean pull. As for not virtualizing |
Ohh, thanks, I missed this point. The hardest thing here is to come up with names. |
…esourceAbstractSource objects, and ResourceCache::GetAbstractFile method.
Thanks for the suggestion! I like it. I pushed my first stab at changing the hierarchy as you described. There is a new method, So the API should remain compatible with existing projects, except for those that depend on the specific hierarchy of I also left the |
I like the idea of supporting PhysFS or any other FUSE-based FS (with compatible license) too. However, I feel a little off with your changes to expose the "Abstract" class all over the code base. Instead we should probably refactor the current File class to become an interface-like class with possible multiple impl classes. The user of the File class doesn't really need to know which impl is being used because the interface (i.e. API to open/read/seek/write) remains the same. Considering that currently our File & Filesystem classes are in fact already versatile enough to support actual file from file system or from package file or from memfs (web) or from APK (android) or from bundle (iOS), adding another one to the mix should not need a massive changes as what I feel you plan to embark. Perhaps I am over optimistic. Speaking of which, do you also plan to share the pieces where you integrate the PhysFS into the engine? I think it would only be fair that after all the changes your proposed which makes our code base more complex than it is, then in the end of day we get the benefit back of having an extra option to use PhysFS for those who want to use it. In short, I hope you are not sharing only the "overhead" bits to us. |
Y no? I mean, there are things to do, but the direction is fine.
Are you talking about refactoring inside the class or splitting logic into separate classes? |
Yes, don’t subclass the File class. I am suggesting to refactor it to have multiple impl similar to Graphics and DbConnection class having multiple impl, but only if PhysFS requires it. I have no issue if it just add another #ifdef in the existing File class. I believe this way we don’t have to confuse the library user to have to dealt with AbstractFile. They use File as it is now, whichever underlying implantation is being used. I hope I explain it clearly. |
I have the following vision of things:
I see. I don't think we should tie ourselves to anythings specific here like PhysFS tho. It's the question of architectural flexibility.
If user want to create a new |
At the moment the current File and Filesystem class are not the same as your view. |
Ohh, that's true... Just checked the code. I meant that both I want to have |
Sorry I am late to the discussion. @weitjong: I intended my mention of PhysFS to mean an example of how such an abstraction could be used. I don't think PhysFS is necessarily suitable for integration into Urho core (it maintains a lot of global state) but if you wish I could add a sample that uses PhysFS, e.g. 51_ResourcesFromPhysFS, that shows how to use the abstraction layer, whenever the final approach is decided. I think abstraction would be more useful than adding another specific use case like PhysFS because it also opens other possibilities, like loading from network, or even IPC. For loading from archives like zip files someone also might want to integrate a lighter-weight library than PhysFS. But again, I am far less familiar than both of you when it comes to Urho's design philosophy. |
But currently we already can load from network and load from compress package file, and it can be achieved without those fancy abstraction layer. |
Specific Urho's compressed package format. The only disadvantage I see is that users will have to replace |
I had no idea Urho could already load resources from network! That's really cool! I can't figure out how it is done, though. Edit: Ah, I see it is through |
It is implemented on the level of |
…e to avoid confusion with similar method in ResourceCache Create ResourceCache::GetResourceAbstractSource method Update a few comments.
@weitjong: Do you have any advice for a solution acceptable to you that allows users to provide their own resource loading solutions? |
Without knowing what is the end goals (integrating PhysFS, or what's not), I think I will not be able to come up with any proposal so I will not take part in this. I am just expressing my personal opinion (dislike) on the new direction, but that's only personal opinion. If there are no other library users making noise (implying the majority of them like it) then you can just proceed. Having said that, when personally if/when in future I see too many things that I don't like that I may just leave the project. I only attracted to this project long ago because its elegance, pragmatic, clean and light hierarchy design approach. |
Personally, I think the essential goal of the changes could be useful. I have a need to load a custom resource package file, which is essentially a filesystem at some abstraction. The idea @weitjong has about multiple file implementations is more along the lines of what I was working towards on my local branch. But I've had very little time to work/think on this recently. |
@weitjong I see at least two end goals.
Actualy I needed the second item some time ago. |
I'm sorry -- I think I've been confusing with my intent, which is not to implement any new specific resource I/O backend. Hopefully I can explain better. You already know this, but all resources are loaded through this method in /// Load resource from stream. May be called from a worker thread. Return true if successful.
virtual bool BeginLoad(Deserializer& source); Since this method takes a However, the actual interface used to load resources (in My intent is: to move towards lifting this restriction while maintaining backwards compatibility in the API. My opinion (which isn't as valuable as that of a senior contributor) is that this is a move towards a cleaner design. As far as I can tell, doing this would require two things: exposure of an abstract deserialization interface (e.g., My intent is not: to implement another specific use case to be available in |
public: | ||
/// Construct. | ||
ResourceRouter(Context* context) : | ||
Object(context) | ||
{ | ||
} | ||
/// Destruct. | ||
virtual ~ResourceRouter() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this unnecessary since Object has a virtual destructor?
Personally, if we are refactoring classes and adding an abstract deserialization interface (above called Another potential use I see in this is that it should be possible to separate the packaged file's code from that of a regular file (though given the present setup works fine,so I don't know if this is necessary). A good test of your system might be to implement the Also, while I don't have a better suggestion for the name, I disagree with the term As a general comment, I like the idea of what you're doing -- lifting the restriction on sources for Files from just the file system and package files (and network requests, I suppose), but I don't like the present way in which you have done it, mostly because of the name changes and the change leaves the present way packed files are handled as just a special case of a normal file, rather than extracting it to a separate implementation that would serve as an example for new implementations (personally I think the present way One other thing I would say about this -- I think you should make the system work such that custom I do have a question as well for anyone who knows -- is there any significant difference between a read-only |
Sorry for the delay in replying -- I've been visiting relatives during the holiday season. Thank you so much for the detailed feedback @SirNate0!
I agree with all of this! This approach does break backwards compatibility in the API however.
Yes, that would be a beautiful application, and probably wouldn't break too much code as I imagine most projects don't use
That seems reasonable. I see that you have a pull request of your own. I do think it is a much cleaner approach, but it does break API compatibility. If the Urho devs think that is an acceptable change, I'm all for it too, I suppose. Thanks again! |
c7346fe
to
b46c83f
Compare
6a26075
to
9c7ea24
Compare
Marking this stale since there has been no activity for 30 days. |
This is the first time I've ever tried to make a pull request on anything... please let me know if I did it wrong.
For a while I've wished that I could abstract the I/O part of resource loading, so I could potentially load resources from a memory buffer, a network request, etc... These are some minimal, non-API-breaking changes that allow someone to do this by subclassing both File and ResourceCache.