Josh @ Dreamland
|
|
Posted on: May 08, 2010, 12:37:01 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
It looks like it's time once again for a poll. Before voting, give Miky / Rusky a chance to present their idea of a Component system, as applicable to ENIGMA. If you have a separate proposal, post it in the same format as I am about to post mine. This format should include the following:
- Code for an object called object0 containing a local "my_local" ----- This should include ALL code required to include necessary locals, particularly those needed throughout the rest of this demonstration - Code for a simple collision function, check_collision(int id), returning bool, utilizing these hypothetical functions: ----- get_object_by_id(int), returning whatever the system requires (probably a pointer) ----- check_rotated_rectangle(x,y,bbox_left,bbox_right,bbox_top,bbox_bottom,image_angle); returning bool - A create event code that shows message "Hello, world! I am at (<x>,<y>)", as it will look when compiled.
My code will have the official names in it, except where a substitute has been given above explicitly. It doesn't really matter what return types are if not specified.
DO NOT vote before a similar description is available for the Component system.
Moreover, I'd say requesting additional code on the behalf of either/any party is fair game.
|
|
« Last Edit: May 08, 2010, 12:41:46 pm by Josh @ Dreamland »
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
Josh @ Dreamland
|
|
Reply #1 Posted on: May 08, 2010, 12:41:48 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Tier System
Instantiable code:
struct ultimate_tier : collision_tier //This includes collision and all lower tiers { //worthless locals shared by all objects go here.
ultimate_tier(): collision_tier() { } //takes care of id and object_index, which are const; myevent_create is in this case inherited from the first tier. ultimate_tier(const unsigned ID, const int ObjectID): collision_tier(ID,ObjectID) { } //takes care of id and object_index, which are const }
struct OBJ_object0 : ultimate_tier //This again includes collision and all lower tiers { var my_local; //Here is the local we're using enigma::variant myevent_create(); OBJ_object0(): ultimate_tier() { myevent_create(); } //takes care of id and object_index, which are const; myevent_create is in this case inherited from the first tier. OBJ_object0(const unsigned ID, const int ObjectID): ultimate_tier(ID,ObjectID) { myevent_create(); } //takes care of id and object_index, which are const } Collision code:
#include "collision_tier.h" bool check_collision(int id) { object_basic *o = get_object_by_id(int); //Fetch an instance of a pointer to the type of the lowermost tier from the instance array object_collision *c = (object_collision*) o; //Assume that it contains locals for our tier. return check_rotated_rectangle(c->x,c->y,c->bbox_left,c->bbox_right,c->bbox_top,c->bbox_bottom,c->image_angle); //Check and return } Create event code:
enigma::variant OBJ_object0::myevent_create() { show_message("Hello, world! I am at (" + string(x) + "," + string(y) + ")"); }
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
Rusky
|
|
Reply #2 Posted on: May 08, 2010, 01:28:06 pm |
|
|
Joined: Feb 2008
Posts: 954
|
Component System
struct SpriteComponent { virtual ~SpriteComponent(int _x, int _y) : x(_x), y(_y) {} virtual void draw() = 0; int x, y; int bbox_left, bbox_right, bbox_top, bbox_bottom; int image_angle, image_alpha; // ... };
struct RasterSprite : public SpriteComponent { RasterSprite(Sprite& s, int x, int y) : sprite(s), SpriteComponent(x, y) {} void draw(); // pretend this Sprite& sprite; };
struct CollisionComponent { virtual ~CollisionComponent() {} virtual bool check_collision(int id) = 0; };
struct Colligma : public CollisionComponent { Colligma(SpriteComponent& s) : sprite(s) {} bool check_collision(int id);
SpriteComponent& sprite; Sprite& mask_index; };
// moved check_collision into the collision component // it uses the sprites instead of manually unpacking all the fields // check_rotated_rectangle would probably be part of Colligma // you could replace it with a vector collision system in another component bool Colligma::check_collision(int id) { Object& o = get_object_by_id(id); return check_rotated_rectangle(o.collision.sprite, sprite); }
struct Object { Object(const unsigned _id, const int obj, SpriteComponent& s, CollisionComponent& c) : id(_id), object_index(obj), sprite(s), collision(c) {} virtual ~Object() {} int& x() { return sprite.x; } int& y() { return sprite.y; } // the rest of the accessors go here unsigned id, const int object_index; SpriteComponent& sprite; CollisionComponent& collision; };
// just... pretend we have a real SpriteComponent implementation struct OBJ_object0 : public Object { OBJ_object0(int x, int y, const unsigned id, const int obj) : sprite(enigma::get::my::sprite::somehow, x, y), collision(sprite), Object(id, obj, sprite, component) {} variant myevent_create();
RasterSprite sprite; Colligma collision;
var _my_local; var& my_local() { return _my_local; } };
variant OBJ_object0::myevent_create() { show_message("Hello world! I am at(" + string(x()) + ", " + string(y()) + ")"); }
|
|
« Last Edit: May 09, 2010, 06:49:06 pm by Rusky »
|
Logged
|
|
|
|
|
|
|
|
Josh @ Dreamland
|
|
Reply #7 Posted on: May 08, 2010, 01:40:40 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Problems: - Lots of "pretending," which I will assume can be overlooked. - "sprite.x", "sprite.y"; am I to traverse every pointer in the system to determine what locals are implemented? In the tier system, I just check ancestors, which is natural. Here, it seems I'm expected to check all members, too.
Perhaps it's also good to show an instance_create(), which is generated code. For this, we can assume the constructor takes an X and Y parameter as well as the other two (instance_create is designed for a 2D system, hence parameters X and Y), and adds the instance into the network for execution. If this is incompatible with a component system, give an alternative.
instance_create(): Tier System
void instance_create(int x, int y, int id) { switch (id) { case object0: new OBJ_object0(x,y,enigma::max_id++,id); break; } }
|
|
« Last Edit: May 08, 2010, 01:42:24 pm by Josh @ Dreamland »
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #9 Posted on: May 08, 2010, 01:48:52 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Here is the snippet, as functions right now in ENIGMA:
#ifndef _COLLISIONS_OBJECT_H #define _COLLISIONS_OBJECT_H
#include "transform_object.h"
namespace enigma { struct object_collisions: object_transform { //Bit Mask var mask_index; var solid; //Bounding box var bbox_top; var bbox_bottom; var bbox_left; var bbox_right; //Constructors object_collisions(); object_collisions(unsigned, int); virtual ~object_collisions(); }; }
#endif
I can not move them back into Object, as that will create an access problem and/or screw up your component. They will be accessing different instances of like-named variables. How do I know they are sprite.x and sprite.y? What tells me that? Yes, that was obvious.
Also, instance_create shows me from where you are exhuming the initial parameters to your constructors.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
RetroX
|
|
Reply #10 Posted on: May 08, 2010, 01:55:27 pm |
|
|
Master of all things Linux
Location: US Joined: Apr 2008
Posts: 1055
|
I wrote C++ with great programming techniques. What's the problem?
No, you didn't. Creating loads of objects purely for organization is not good programming technique. There are easier, more efficient ways of organizing things, and in fact, it removes readability rather than adds it.
|
|
|
Logged
|
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)Why do all the pro-Microsoft people have troll avatars?
|
|
|
|
Josh @ Dreamland
|
|
Reply #12 Posted on: May 08, 2010, 02:01:01 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Retro: The point only seems to be organization on this level; this is about adding and removing functionality with as little a ripple as possible.
So yes, I'm still waiting on an explanation for the origin of "sprite." and the constructor parameters in all that mess.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
luiscubal
|
|
Reply #13 Posted on: May 08, 2010, 04:01:38 pm |
|
|
Joined: Jun 2009
Posts: 452
|
Both systems are pretty simple to understand:
Josh's tiers: Think of a stack of pizzas. Each pizza is functionality. The graphics pizza, the collisions pizza, etc. On top of everything, you can put your object pizzas. Removing/Replacing tiers in the middle might be problematic, although Josh seems to consider those problems edge cases and, therefore, unlikely to be harmful and/or too much inconvenient.
Rusky's components: Instead of pizzas on top of each other, think a bunch of blocks side by side. Because they are not on top of each other, they will not fall if you take on from the middle. On top of those blocks is the object block. Rusky's system is designed so that replacing blocks is embarrassingly easy(and removing blocks isn't too complex), this at the expense of a few extra CPU cycles, which Rusky seems to consider irrelevant because CPU cycles are very fast and, therefore, the difference is unlikely to be noticeable.
Creating loads of objects purely for organization is not good programming technique. I have to disagree. Abstractions are part of computer science and engineering. Otherwise, we would still be coding the computer directly, without programming languages not even kernels.
|
|
|
Logged
|
|
|
|
|
|