GenuineXP

Members
  • Content count

    510
  • Joined

  • Last visited

Community Reputation

262 Neutral

About GenuineXP

  • Rank
    Advanced Member
  1. To PIMPL or not To PIMPL

    Interesting, I was just wrestling with the same issue in some of my code. I realized since I was maintaining the implementations using boost::shared_ptr objects that the so-called implementation hosts could be used as value types. However, this lead to some confusing syntax (IMHO) and the problem that any data not stored in the implementation but rather in the host object would lead to unnecessary copying (in my case, copying shared signal objects). I too have decided this isn't very desirable. :-) I have also adopted a simple class-level typedef for pointer types as mentioned previously in this thread. class graphics_context : ... { ... public: typedef boost::shared_ptr<graphics_context> ptr; typedef boost::shared_ptr<const graphics_context> const_ptr; ... }; I think this will be much more obvious to users. There's also the problem of deferring instantiation, which would not be possible using value semantics.
  2. Yes, I see now that intelligently handling the loading and unloading of resources is a problem not solved by Boost.Flyweight. It doesn't look like it's very suitable for resource management in a game, and as you stated, building a hash table by hand isn't difficult anyway. That's about all it provides here. Thanks for the input. :-) It's a cool library, and I wanted to explore the applications.
  3. Quote:Original post by Telastyn It's the intelligent caching and being able to sufficiently abstract 'how do I load X if it's not there?' variability... Good point. Since they're using a hash table under the hood (at least I assume so), I would hope that caching would also be handled reasonably well by using boost::flyweight objects. Since I would identify resources (statically) with a unique ID, the whole, "How do I load x if it's not there?" part is a matter of the flyweight seeing that the expected ID isn't already in use and constructing a new object (which in turn actually loads the content). I would most likely use strings for IDs and not integers as I did in the above code. As long as resources are always referred to by ID, the flyweights could keep things tidy. ... texture_handle tex0("some-awesome-texture"); // Key not already in use, so construct a texture object, loading the data with that ID. texture_handle tex1("another-amazing-texture"); // Key not already in use; same deal. ... texture_handle tex2("some-awesome-texture"); // Key has been used, so just reference the existing object. ... I figured I would experiment with this in a sort of "package" system I'd like to use. It at least seems to solve part of the problem of resource management. One thing I haven't thought of until now was releasing resources allocated this way. I'm not sure boost::flyweight provides a mechanism for that. Any chance anyone has actually used or attempted this before?
  4. So I've taken a look at the Boost.Flyweight library and it seems quite nifty. I'm curious if it would be good for resource management though. For example, would a setup like the following be reasonable? (I did not try to compile this code; there are probably mistakes.) class resource { public: typedef boost::uint_fast32_t id_type; virtual ~resource(); id_type get_id() const; private: id_type id_; }; struct resource_id_extractor { resource::id_type operator()(const resource &r) const { return r.get_id(); } }; std::size_t hash_value(const resource &r) { boost::hash<typename resource::id_type> hasher; return hasher(r.get_id()); } bool operator==(const resource &lhs, const resource &rhs) { return lhs.get_id() == rhs.get_id(); } typedef boost::flyweight<boost::key_value<typename resource::id_type, resource, resource_id_extractor> > resource_handle; class texture : public resource { }; This would index resources by a unique ID. Coupled with a package system that assigns a unique ID to resources stored on disk, it looks like Boost.Flyweight would provide all the plumping for quick and easy lookup and management of those resources. What do you think? I'm interested in what people think about the library in general as well. Thanks.
  5. I'm trying to embed Python into a game and have some questions about it. More specifically, I'm trying to use Python to implement parts of a component-based system I'm working on. I'm using Boost Python. All I've done so far is tinkered with the Boost Python wrappers around the Python C API and I've managed to load scripts and evaluate free functions. Eventually, I'd like to be able to: 1.) Load scripts and evaluate generic objects. Given a symbol name "foo", I want to be able to extract its value, whether it be a callable object (like a free function) or a simple variable within the __main__ dictionary. 2.) Expose an API to Python scripts, giving them access to a component object, which is exported from C++. I'm sure these are common ideas. I was wondering if anyone is willing to share their thoughts, experiences, and maybe even code regarding all of this. How have you embedded Python? How do you typically handle the loading and execution of scripts? I don't think I need too much power or low-level functionality (just evaluating objects should be enough). How do you generally go about exposing an API to Python? I think that may be the most difficult part. So far, I'm surprised at how easy it can be to get a Python script running and to extract values from it. Thanks!
  6. Polymorphism and templates

    The error message is spot on. You simply cannot create virtual member function templates in C++. One way to get around this (sometimes) is often called a concept, where you supply a class as a template parameter that should provide some interface and implements said concept. template<typename T> class foo { public: void bar() { T::baz(); } }; I'm not sure what you're going for, but maybe that can be helpful. EDIT: Ah yes, as Nanoha said, creating a class template rather than a template member function may also get around the problem and would probably be cleaner than using the technique I described.
  7. That bit of reasoning sounds good to me. But how do I determine what's a serious enough error to warrant an exception? As an example, for working with raster data in memory, my library provides an image class (actually, image is a proxy that manipulates an underlying plugin object, but that's beside the point). image provides a simple crop member function. Like many of its other member functions, crop returns an integer value indicating the success or failure of the action. One exceptional case is a client call to crop on an image that hasn't been loaded (contains no data). Surely this is not a fatal problem, and effectively renders the call a no-op. So, would this be a good place to forgo exceptions? This situation is very similar to many of the other cases where I've considered using exceptions. Namely, the general problem is calling member functions on objects that don't have an acceptable state (such as swapping the back buffers on a graphics device object before opening a display mode). I suppose I'll employ exceptions, but only where a seemingly unrecoverable problem has occured (i.e., not in the above cases).
  8. Quote:Original post by swiftcoder ...not only will a copy be compiled within the client code, but a separate copy will be compiled inside the library... Nice catch. :) I didn't think about that when I laid that out. I'm still unsure of whether or not I should go ahead and use exceptions? What have others here done in libraries/engines? I'm really not concerned with the performance hit (something I've seen mentioned on these boards in the past), since I'm really not convinced it's significant (unless I'm constantly throwing exceptions for some reason).
  9. Hm, so distributing a static library won't really help in any way then? What would be a good compromise? I could use exceptions, but encourage users to compile my source code themselves and link statically, or I could forgo exceptions entirely and resort to annoying error codes. If I choose to abandon exceptions, would it be worth the trouble then to disable the use of exceptions entirely when I compile the library? Otherwise, the standard library may throw whatever it pleases, potentially causing a crash rather than an opportunity to handle the problem. Another thought: is it at all possible to wrap code within a header so that exception throwing is always compiled into client code? Something like this. foo.hpp ... class foo { public: ... void bar() { if (do_bar() & some_error_mask) { // Do the real work and check for errors. throw std::runtime_error("bar!"); // Okay to throw exceptions here; it's compiled into client binaries. } } ... private: ... int do_bar(); ... }; foo.cpp ... int foo::do_bar() { // Implement the real work here. return send_all_energy_to_flux_capacitor(42, "McFly"); } ... Thanks for the insight!
  10. Well, the question is summed up in the subject! I'd very much like to use exceptions in a library I'm writing. The problem is, I know how dangerous they can be if the library is compiled into a shared binary (e.g., a DLL or shared object). The good thing is, I think the binary portion of the library will remain fairly small, so static linking is an option. If clients statically link with my code, are exceptions less dangerous? I imagine that they are, since both the client's code and my library code will be linked (or even compiled) by the same tools. If this isn't the case, how can I best support exceptions without making very picky binaries? Thus far, I've been trying to keep any exceptions my code explicitly throws within the library and then resort to error codes. Yuck. If I can avoid this, that'd be great. So... static linking! Better for exceptions? Thanks.
  11. I haven't started playing with this yet, so I figured I'd ask about it here first. I have a library whose implementation is loaded at runtime. I'd like to be able to report the supported capabilities on a given platform to client code. For example, if the implementation on a target system uses libraries that are unable to load PNG files, but can load JPEG files, clients should be able to use an API to discern this. I'm working in C, btw. Has anyone worked on something like this before? The simplest thought I've had about it is to include some capability enumerators and structs in the library. Then clients can use functions that simply return a list of said enumerators, each representing a capability. In addition, it would be necessary to associate some values with these enumerations (for example, texture support should include details like maximum texture dimensions). I'd like to avoid creating a myriad of functions that each query a single capability. The alternative seems to be to have functions that query a family of capabilities at once, such as graphics capabilities. Anyway, I'm just looking for tips or ideas on how I may want to go about designing/implementing this API; I'm trying to avoid pitfalls. Keeping it simple would be nice, but I'd also like to make something that's robust. Any insight is appreciated. Thanks!
  12. Hm, what exactly are you trying to accomplish; I'm not sure I get it. It sorta sounds like what you're looking for are threads. If I'm understanding correctly, you want to be able to collect user input while continuing to execute the body of the loop (i.e., don't block in a call to std::getline or the like). Is this what you're shooting for? Perhaps you're trying to capture a single character at a time?
  13. Whoops. Forgot to perform the multiplication in my example code here (it's in my source code though)! Sorry.
  14. So I've actually managed to get away with this in C using GCC in Linux. #define SIZEOF_FOO_INT ( sizeof(int) * 8 - 1 ) #define SIZEOF_FOO_FLAG 1 struct foo { int bar : SIZEOF_FOO_INT; int baz : SIZEOF_FOO_FLAG; }; size_t max_foo_int() { return ( INT_MAX ) >> ( SIZEOF_FOO_FLAG ); } size_t min_foo_int() { /* Bit tricks here. */ } /* Other convenience functions here. */ Please forgive the silly names; I just wanted to throw something together here. I'm wondering, how safe/standard is this? To be more specific, I'm referring to the usage of the sizeof operator to deduce the size of the 'bar' field at compile time. I'm doing this because I need to be able to apply a 1 bit flag to integers of native platform size. For example, on systems where 'int' is 32 bits in size, I want to be able to use 31 of those bits normally (for storing integer values) and 1 of those bits as a flag. On systems where 'int' is 64 bits in size, I want to be able to use 63-bit integers with a similar 1-bit flag. An important assertion is that sizeof(foo) == sizeof(int). This has been working on my development platform, but is it a safe assumption for other platforms as well? In practice, I use macros that apply packing to structs for certain compilers to avoid unnecessary alignment adjustments. Am I off my rocker, or is this a sane approach to getting what I want here? Thanks! EDIT: Added missing multiplication in SIZEOF_FOO_INT macro. [Edited by - GenuineXP on February 13, 2009 11:51:05 AM]
  15. malloc to new

    I haven't looked at the code because you simply haven't asked anything here. What are you trying to do? Are you worried about the correctness of your code? Will it not compile? These are all questions you need to address when posting, otherwise no one can help you. You probably want to start with what you're trying to accomplish and an overview of the problem. You may find that your approach may not be the best, and people here can give you better alternatives if possible. Good luck.