Quote:myModel& monster = Model( "BigMonster" );
This is not legal C++. Temporaries may not bind to non-const references.
Quote:myModel& monster = Model( "BigMonster" );
Quote:Original post by loufoqueQuote:myModel& monster = Model( "BigMonster" );
This is not legal C++. Temporaries may not bind to non-const references.
Quote:Original post by Zahlman
Hold on. Let's take a step back first.
Why do you have managers?
What do they do?
Quote:Original post by Antheus
And voila, the spaghetti are untangled.
To load a model, you call your Asset class instance, and use loadModelFromFile utility method.
Quote:Original post by Nairou
However, if you ignore all of the logical restructuring you did, aren't you just trading what dependency needs to be passed around?
class Assets { FileSystemManager filesystemManager; MaterialManager materialManager; Assets(FileSystem fs) { filesystemManager = fs; materialManager = new MaterialManager(fs); } Model loadModelFromFile(string s) { // implemented above }};
Quote:Rather than creating a Model object, and passing the Filesystem and Material references to it, you're being passed a central Assets reference and loading the model from there.
int main() { FileSystemManager fs = new FileSystemManager(); Assets assets = new Assets(fs); Model m1 = assets.loadModelFromFile("mesh1");};
This is as simple as it gets.int main() { FileSystemManager fs = new FileSystemManager(); Source s = new ModelLoaderSource(fs, materialManager); Model m = new Model(s);}
Same thing, but since I will need to create more than one model, I might as well wrap it into a factory. The important thing is, the design is highly decoupled, and I can now perform changes like these with minimal impact.Quote:the desire to still provide clean APIs for the rest of the code to use.The above is clean API. User uses Assets instance to create meshes. It doesn't matter where it comes from. You can provide an existing instance, a global (not singleton, since there can be multiple), or they can create one on their own.
Model::Model(Vertex v[], int nVert, Tri t[], int nTri, Texture * tx[], nTex);
Because this is really what a model is. Loading is orthogonal functionality which almost all serialization tools implement externally, but often expose it either via member functions or in constructor.Quote:What I try to do is minimize the coupling until it boils down to bare minimum. I would likely factor out both filesystemManager as well as materialManager, but I don't know what they do, so I can't.
Quote:Original post by Nairou
I can see how my Material class could be factored out (as long as you provide a Filesystem reference, it consists of little more than a loader function that outputs complex structs), but I'm curious how you would factor out the Filesystem class (as an example).
Quote:Granted, it too consists of little more than a loader function. However, it does contain a private std::map, where it caches the data it loads.So it's a cache. Why not call it as such.
Quote:That map still needs to exist somewhere, so the only factoring I can think of is to make it static and turn the Filesystem into a purely static class.
Quote:How would you handle this?Like I demonstrated above. User allocates the instances. If they choose so, they can make them static.
Quote:Original post by loufoque
If you want a clean API, I would suggest to stop mixing Java (or is that C#?) and C++, and even not to code Java-style at all in C++.
Quote:int main() { FileSystemManager fs = new FileSystemManager(); Assets assets = new Assets(fs); Model m1 = assets.loadModelFromFile("mesh1");};