Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

258 Neutral

About TomH

  • Rank

Personal Information

  • Interests

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I'm disappointed this article is not actually about unreal engine (as other have already pointed out it's really just marketing material for PVS-Studio)   The marketing material is interesting and reads nicely, but it would IMO have been more trustworthy, with a name/ description/ introduction that identified this article as a use case for PVS-Studio on large projects. (I guess what I'm trying to say is I would have preferred the article not to pass itself off for something it isn't)
  2. Your first post got me wondering, what are the alternatives to casting for doing operations on the raw pointer. Admittedly this is still deep in "hack country", but you can use template specialisation to provide the operations you want - in reality this is not much better than macro magic (#define private public, #include weak_ptr...) A solution would look something like this: #include "boost/weak_ptr.hpp" #include "boost/functional/hash.hpp" #include <iostream> namespace { struct WeakCmpOp { }; } namespace boost { template<> class weak_ptr<WeakCmpOp> { public: template<typename T> static std::size_t hash( const weak_ptr<T>& victim ) { boost::hash<T*> hasher; return hasher(victim.px); } template<typename T> static bool isEqual( const weak_ptr<T>& victimA, const weak_ptr<T>& victimB ) { return victimA.px == victimB.px; } }; } using namespace std; int main() { boost::weak_ptr<int> ptr; cout << "count = " << ptr.use_count() << endl; cout << "hash = " << boost::weak_ptr<WeakCmpOp>::hash(ptr) << endl; cout << "test = " << boost::weak_ptr<WeakCmpOp>::isEqual(ptr, ptr) << endl; return 0; } On balance this sort of thing will probably "bite you" sooner or later - but it was fun figuring out how it can be done ;)
  3. I haven't really thought this through, but one way to "hide" your weak_ptr operator== from general use. Use unordered_set's Pred template parameter, this defaults to std::equal_to<Key> - which I guess in turn calls operator==. If you provide your own predicate it can call any function you like (or even include code from your operator directly) This would allow you to avoid operator== and write code using a function name that does not expose a change to weak_ptrs.
  4. TomH

    [C++] Exception handling

    Fair enough, I think that's a good decision. For the record I should probably correct a few point in my original reply. When using shared_ptr and shared_arrays, you don't need the auto_ptr. A local shared_ptr on the stack will ensure resource are correctly released. This would make the example something like: class Sprite { private: boost::shared_array<int> m_pArray; boost::shared_ptr<Image> m_pImage; ... Sprite::Sprite() { // Perform all the actions that can throw, storing allocated resources // on the stack in a reference countered smart pointers boost::shared_array<int> array ( new int [100] ) ); boost::shared_ptr<Image> image ( new Image ); // Now perform assignments from the stack based smart pointers into // class members. Once starting these assignments don't call anything // that can throw m_pArray = array; m_pImage = image; } Sprite::~Sprite() { // Releasing m_pArray and m_pImage is done by the boost::shared_array and boost::shared_ptr }
  5. TomH

    [C++] Exception handling

    Hello ppetruzalek, Leaving aside the questions about whether exception are the right tool for this job, the "standard" approach to this problem is using two library classes: std::auto_ptr<T> and boost::shared_array<T>. The basic idea is that as an object's constructor is executed, any resource that are allocated is stored via auto_ptrs on the stack. The auto_ptr provides the behaviour that when it goes out of scope (is destructed) it will destruct the object to which it points. This in combination with the fact that throwing an exception causes the stack to be unwound means that if an exception is thrown within the Image constructor (and not caught by the Sprite constructor). The stack based auto_ptrs go out of scope and these in turn call destructors for any resource that has already been allocated. The only piece that is missing is what happens if everything works. In this case once all the allocations have completed then resources are assigned from the auto_ptrs into member variables. At the point of assignment the auto_ptr stop managing their resource (so they don't destruct resources when the constructor ends normally) As an exercise for the reader take a look at: auto_ptr info shared_ptr docs shared_array docs I don't have access to a compiler at the moment, but the code should look roughly like this: class Sprite { private: boost::shared_array<int> m_pArray; boost::shared_ptr<Image> m_pImage; ... Sprite::Sprite() { // Perform all the actions that can fail (throw), storing in an auto_ptr on the stack std::auto_ptr<boost::shared_array<int> > array ( boost::shared_array<int>>( new int [100] ) ); std::auto_ptr<boost::shared_ptr<Image> > image ( boost::shared_pointer<Image> ( new Image ) ); // Now perform assignments from the stack based auto pointer into the class, until the constructor // completes don't call anything that can throw m_pArray = array; m_pImage = image; } Sprite::~Sprite() { // Releasing m_pArray and m_pImage is done by the boost::shared_array and boost::shared_ptr }
  6. Hello Muse, I think what nobodynews' examples are getting at is that it is possible to produce MCDC (Modified Condition Decision Coverage)coverage by instrumenting a high or mid-level language such as C and then recompiling it. As far as I'm aware this is the approach of tools such as LDRA and Cantata. // Original Code if( expr1 || expr2 ) { ... } if( expr3 || expr4 || expr5 ) { ... } // Instrumented Code if( conditionalHook(x,1,expr1) || conditionalHook(x,2,expr2) ) { ... } if( conditionalHook(y,1,expr3) || conditionalHook(y,2,expr4) || conditionalHook(y,3,expr5) ) { ... } The key thing here is that conditionalHook returns its expression parameter and records the value of its parameters. So in this example for conditional coverage on the first if statement you'd need to have seen the following calls into conditionalHook: (x,1,true), (x,1,false), (x,2,true), (x,2,false) - This can all be checked after the fact provided everything is saved off to a database or log file. Cheers, Tom
  7. Hello Elih1, I believe the problem here is SEH and C++ stack based objects can't be mixed in the same *function* (Which is virtual what the error message is saying). So moving the contents of your __try block into a nested function should fix this problem. See the following links for more details: Object Unwinding Mixing C (Structured) and C++ Exceptions Exception Handling Differences Also I'd ask if you have considered switching from SEH to C++ exception handling (try, catch, etc.) as again this should fix your problem. Cheers, Tom
  8. I'm happy to be of help. Quote: I don't like Hungarian Notation, i think it goes against the idea of scope. It's ok for C but in C++ names should not carry and extra information, that's what "this->" is for. I guess i should be consistent, i just can't be bothered writing "this->" everywhere. Technically this is not Hungarian Notation which deals with type information not scope information* ( variable is int, rather than variable is member data ) Personally I find a naming convension that help distingish between: member (instance) data, class (static) data and function scoped variables very useful. However (flame) wars have been fought over much less than discussions on variable naming so time for me to shutup :) *Actually some variants Hungarian Notation also include scope information, but I'd argue that if you remove type information you are no longer using Hungarian Notation. Cheers, Tom
  9. Hello XTAL256, From a quick look at the SOIL documentation I don't think you can use SOIL_load_OGL_texture_from_memory on the image returned by SOIL_load_image. As SOIL_load_image returns a pointer to an array of pixels (after decoding the image file format). And SOIL_load_OGL_texture_from_memory is expecting its buffer to contain the data in one of the file image formats ( TGA, PNG, BMP, etc. ) - an image before it has been decoded. From the SOIL documentation: /** Loads an image from RAM into an OpenGL texture. \param buffer the image data in RAM just as if it were still in a file ...snip... **/ unsigned int SOIL_load_OGL_texture_from_memory ( const unsigned char *const buffer, int buffer_length, int force_channels, unsigned int reuse_texture_ID, unsigned int flags ); I suggest you try using SOIL_create_OGL_texture instead of SOIL_load_OGL_texture_from_memory which appears to create a texture from raw image data. Again a snippet from the SOIL documentation: /** Creates a 2D OpenGL texture from raw image data. Note that the raw data is _NOT_ freed after the upload (so the user can load various versions). \param data the raw data to be uploaded as an OpenGL texture \param width the width of the image in pixels \param height the height of the image in pixels \param channels the number of channels: 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture) \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT \return 0-failed, otherwise returns the OpenGL texture handle **/ unsigned int SOIL_create_OGL_texture ( const unsigned char *const data, int width, int height, int channels, unsigned int reuse_texture_ID, unsigned int flags ); As an aside the "this->" pointer is optional* when accessing member data and it's a matter of personal preference whether to write it or not, but I would suggest you are consistent and use it everywhere or not at all (i.e. on width, height, origWidth, origHeight and id) I should also point out that most people omit a "this" pointer and name their data members to indicate that they belong to a class instance, typical prefixes are things like "m_" and "my" (m_Id or myId). *Sometimes it might be necessary to qualify data member access with a "this" pointer, for instance if local variables are using the same name as the member data (and possibly when working with templates, but I wouldn't worry about that) Cheers, Tom
  10. Rene_G, I agree it might be worth dropping the state pattern as it seems to be creating a muddled design, when you try and factor out common entity behaviour. One question that springs to mind is how many states are you expecting to have? If you wanted to continue using this pattern then in answer to your questions I would have suggested the following: 1) Mirror the Entity hierarchy in the EntityData hierarchy and pass EntityData from the most derived constructor, i.e. class EntityData; class Entity { protected: // Constructor for derived classes that // want to specialize EntityData Entity( EntityData* data ) :m_Data( data ) {} private: EntityData* m_Data; }; class EntityButtonData : public EntityData { ... }; class EntityButton : public Entity { public: // Constructor for 'normal' use, this // Entity's data is an EntityButtonData EntityButton( ... ) :Entity( new EntityButtonData( ... ) ) {} protected: // Constructor for derived classes that // want to specialize EntityButtonData EntityButton( EntityButtonData* data ) :Entity( data ) {} }; It's slightly dodgy, but given the constructors enforce fact that the EntityData is either their data type or a derived class it *should be* safe to add the following code: class Entity { protected: EntityData& data_storage(){ return *m_Data; } }; class EntityButton { protected: EntityButtonData& data(){ return static_cast<EntityButtonData&>( data_storage() ); } }; 2) Now there are several approaches to getting the EntityData into into EntityState classes: 2a - Store the reference/ pointer to the (derived) EntityData in the EntityState on construction of the state class, much like your original example. 2b - Cast the parameter and rely on the fact that EntityButtonState classes should only be dispatched events from EntityButton classes, that "will always" contain EntityButtonData dervied classes. 2c - Change the parameter type and use a family of dispatch functions when passing events into EntityState classes. This is where things could get interesting and complicated :) In its simplest form the despatch functions would be of the form: Note the state interface is now specific to EntityButtonData. void EntityButton::OnMouseMove(float x, float y) { CheckState(); if (m_state) m_state->OnMouseMove(data(),x, y); } This really starting to look messy and requires a lot of typing, but it can be templated away using something of the following form: (this recursive template usage is known as the "curious recusive template pattern") template< class TEntityClass, class TEntityDataClass >; class EventDispatcher { class StateInterface { virtual void OnMouseMove(TEntityDataClass& data, float x, float y); ... }; ... void OnMouseMove(float x, float y) { CheckState(); if (m_state) m_state->OnMouseMove(data(),x, y); } ... private: StateInterface* m_state; StateInterface* m_newState; }; // EntityButton is 'recursively' passed into the template class EntityButton : public EventDispatcher<EntityButton, EntityButtonData> { ... }; After writing all that I suspect this isn't the best way to go forward, however getting everything working together might well be a interesting challenge and learning experience. Cheers, Tom
  11. Hello Rene_G, Quote: I think of it like this: Entity is the representation of what is on the screen. But Entity has no behavior. The behavior is completely controlled by states. However, the states changes the representation, and acts on specifics of the representation. But noone else should have access to these details on the representation. I can just about see where you are going with this, there are a number of ways this can be achieved: 1a) Move Entity's data into another class, say EntityDetails. Change Entity to contain an EntityDetails by value, then pass a reference to EntityDetails when delegating an event to the current state, i.e. class EntityState { ... virtual void OnMouseMove(EntityDetails& entityDetails, float x, float y); ... }; Now because you control EntityDetails by only passing it to EntityStates (and not providing any direct accessor from Entity) It would probably be reasonable to expose methods that access the (current) specific representation of your entity data. This will avoid the need for friend access and associated problem with EntityState subclasses. As an extra point passing the EntityDetails into each method's call avoids the cyclic reference you get from storing a pointers between state <-> entity. And allows a single EntityState object to be shared by multiple Entities. 1b) You could achieve the same effect by using inheritance to separate EntityInterface and EntityImplementation, the interface contains your current Entity methods as pure virtuals and the implementation contains the your data, the current method implementations and methods needed to update your data. 2) Move the data EntityState. 3) Update EntityState to expose Entity data that its friend access allows, i.e. BTW: I think this is really dodgy approach, but it does have the advantage of being the simplest change from you current code. class EntityState { ... protected: static float& ma_left( Entity& entiry ) { return entiry.ma_left; }; ... } I'm sure there are many other approaches, my advice it to pick one try it and learn from any mistakes you later recognize. Personally I'd choose option 1a, but that's just me, Cheers, Tom
  12. TomH

    uploading files to a server

    Hello CProgrammer, (Disclaimer: I don't really know much about this so maybe completely wrong) I'm assuming you're are talking about a flash script that the user has just downloaded and its ability to upload (access) files on the local machine. I would guess this comes from the restriction that flash action script is not allowed to access the local file system. In the case of uploading a user selected file to the server the flash script is not "really" accessing the local file system, rather it is asking the browser to upload a file to the server. Because the browser is uploading the file, the file's contents are not available to the flash script - As providing access to this file during upload would allow the script (limited) read access to the local file system. Obviously once the file has been uploaded to the server it can be sent back into flash as a downloaded (non-local) file and you can do anything you want with it. In your case modifiy and upload the modified version. As an aside, I've just seen an interesting proposal that flash should have an API for accessing user selected files (Local File Access API) however I can't see any sign this has been taken up. If you want to avoid sending your local files on a round trip to the server then the one alternative I can think of is: - Provide a signed Java applet that communicates with your flash component. Once your the applet's and certificate has been accepted it will have access to the local file system. Unfortunately using the applet the user can when no longer control local file access by selecting individual files, and is now at the mercy of the code within the applet and flash component. Cheers, Tom
  13. Hello RedAnt, How about factoring the specialized code out into a non-template helper function? This helper function can then be called from the template specialization. This will allow headers that are only used by the helper function to remaining out of the templated header file. For Example: Adding the helper function "formatParameterValueForWriteStringImpl" // general template (definition in the same header file but outside the class) template < typename SourceValueType > static dword formatParameterValueForWrite( const SourceValueType& value, const USS_ParamDesc& desc ); // specialization for T = String (definition in lined in the class, calls non-template worker function) template <> static dword formatParameterValueForWrite< String >( const String& value, const USS_ParamDesc& desc ) { return formatParameterValueForWriteStringImpl( value, desc ) }; // non-templated worker function (definition in a cpp) dword formatParameterValueForWriteStringImpl( const String& value, const USS_ParamDesc& desc ) { ... perform the real work here .. } Cheers, Tom
  14. Another alternative to Jam is SCons, again a multi-platform build system. One of its more interesting features it the ability to generate MSVC project files which depending on your choice of IDEs might prove useful. link: Scons Website Cheers, Tom
  15. Hello CipherCraft, I'm a little slow on responding to your original question. But if you run into problems with JTrac, then I'd suggest trying Roundup (http://roundup.sourceforge.net/). I've been using it at work for more than 6 months and I've been impressed with its "light weight" approach to issue/bug tracking - basically it provides a very minimalist interface that allowed me to quickly raise, comment and close bugs. I can't comment on the installation process, as someone else installed it. Cheers, Tom
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!