Jump to content

  • Log In with Google      Sign In   
  • Create Account


GorbGorb

Member Since 25 Jun 2011
Offline Last Active Sep 20 2012 04:39 AM
-----

#4929702 Using RTTI in an entity component system?

Posted by GorbGorb on 09 April 2012 - 05:51 PM

I mentioned JavaScript above:

var Enemy = function() {
  this.velocity = [1.0, 2.0, 3.0];
  this.mass = 200.0;

  systems.install(this);
}

With some template magic and type erasure this can actually be emulated in c++, for example, I use this:
prototype p = system_manager.new_prototype();
p.add_component( velocitity{ x , y , z } );
p.add_component( mass{ 200 } );
entity a = system_manager.new_entity( p );
entity b = system_manager.new_entity( p );
which doesn't look that much worse. The idea is to have references to base_system s in your system_manager. During its initialization, you create a map< typeinfo , unsigned int >, where the value type is unsigned int. When adding a component to a prototype (usually while loading a level) you lookup that system_index in the map once and store it with the component. To create an entity from a prototype you simply iterate over all components in it and do
systems[ system_id ].insert( component );

Maybe I'll refactor my implementation a bit and upload it somewhere, it is, as you said, quite some work to implement a generic component system in c++.


#4916170 Organizing and managing code?

Posted by GorbGorb on 24 February 2012 - 06:00 AM

-Every time you use a 'new' keyword to allocate memory, automatically create a 'delete' keyword to deallocate it and make sure that the delete is reached.

Don't use new unless you need a custom data structure or for unique_ptr. Use std::make_shared and std::vector instead (you could also create std::make_unique, I'm sure it'll make it into the standard soon).
A *a = new A;
//use a
delete a;
is very like not exception safe. Better:
std::unique_ptr< A > a( new A() );
//use a
//std::unique_ptr deletes a
You don't leak memory if you use modern c++.


#4872504 C++ template class, specialized member function/operator

Posted by GorbGorb on 14 October 2011 - 07:11 AM


template<typename T> class Foo

{

	T m;

	

	operator int() const

	{

		return int(m);

	}



	//Lots of other member functions ect.

};

template<>

Foo<int>::operator int() const

{

	//specialized version

	return 0;

}




#4859437 [C++] Looking for feedback on my event system

Posted by GorbGorb on 09 September 2011 - 05:24 AM

Ok, although I don't use std::function too often, I noticed some things to improve:
- you are leaking memory
- why don't you just let users register a std::function object directly?

In addition, you could hide some boilerplate (event id , event base ) with this technique:

unsigned int next_id()
{
  unsigned int previous_id = 0;
  return ++previous_id; //or return previous_id++ , depending on wheter you need a NULL value
}
template< class Type >
class type_id
{
public:
  static unsigned int value;
};
template< class Type >
unsigned int type_id< Type >::value = next_id(); //unique value for each type
After that, the register and disptach functions would just look like this:
template< class EventType >
void register( std::function< void( const EventType &) > callback )
{
  unsigned int id = type_id< EventType >::value;
  //...
}
template< class EventType >
void dispatch( const EventType &event )
{
  unsigned int id = type_id< EventType >::value;
  //...
}
That way, you can use any type you want (e.g. an int or an std::string) as an EventType and save a lot of boilerplate and bugs because you can't accidentally use a wrong event id.

To save the map lookup, you could use a vector whose size is as big as the number of EventType s you have instead of a map.
(to do is, check in register and dispatch whether your vector is large enough and resize it if needed).
Then you can just access the listener_vector for any type T with
listener_vectors[ type_id< T >::value ];
which has O(1), but probably consumes more memory if you have multiple dispatchers.


PARTNERS