Can we do this? if we can, what does it call??

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Hi team

Say we have a function that run a robot - runRobot(), and it take a robot structure, and this structure contains necessary information for runRobot() to do stuff:

Code:
typedef struct ROBOT_OBJ{
    uint8_t health;
    uint8_t attack;
    uint8_t block;
}robot_obj_s;

robot_obj_s simple_robot;

runRobot(simple_robot)
Say I want to add a special skill to this robot, and I define a structure for special skill like this:
Code:
typedef struct SKILL_FLY{
    uint8_t max_speed;
    uint8_t booster;
    uint8_t steering;
    ...
}skill_fly_s;
And I want to be able to add to my robot by simply adding the new skill to the robot structure without modifying my runRobot() code like this:
Code:
[CODE]typedef struct ROBOT_OBJ{
    uint8_t health;
    uint8_t attack;
    uint8_t block;
    skill_fly_s skill_fly;        /* added new skill    */
}robot_obj_s;

robot_obj_s simple_robot;

/*!
*    my runRobot() function can regonizse this new skill
*    without me rewritting the runRobot() function
*/
runRobot(simple_robot)
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
My question is can this be done? I am sure it can, as I think games are done this way, but how?? And what this call? How do I write my runRobot() and structure my structure to implement this?

What do I need to google for to find out more about this?

Thanks guys!
 

WBahn

Joined Mar 31, 2012
32,883
When you compiled your runRobot() code any references to anything in the structure passed to it were turned into offsets from the address of the pointer that was passed. It has no idea that skill_fly exists, let alone how to access it or what to do with it even if it could access it.

Now, you could come up with a file-based data structure that might be flexible enough to do what you want. It would be challenging, but doable. There are also languages that are much better suited to dynamic code. Most of them are interpreted, which makes doing dynamic stuff like that a lot more tractable.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
When you compiled your runRobot() code any references to anything in the structure passed to it were turned into offsets from the address of the pointer that was passed. It has no idea that skill_fly exists, let alone how to access it or what to do with it even if it could access it.

Now, you could come up with a file-based data structure that might be flexible enough to do what you want. It would be challenging, but doable. There are also languages that are much better suited to dynamic code. Most of them are interpreted, which makes doing dynamic stuff like that a lot more tractable.
Hi @WBahn, sorry I didn't make it clear, I wasn't intending to do it dynamically. I am more interested in doing this during development. My idea was once the runRobot() is written. Then I can focus on writing feature sets, it will be very powerful if it can be done.

I guess the closing thing I can get is inheritance from C++.

Never mind about me, I think it's just another random idea I have :)
 

djsfantasi

Joined Apr 11, 2010
9,237
It can be done... the question is how.

I have written a pre-compiled interpretive language to control robots.

The hardware is abstracted from the run-time module so new hardware or functions can be added with a minimum or no code modifications.

Since the control is defined by the language, the run-time module does not need modification. And the code “scripts” or routines, which makes adding new actions simple.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
It can be done... the question is how.

I have written a pre-compiled interpretive language to control robots.

The hardware is abstracted from the run-time module so new hardware or functions can be added with a minimum or no code modifications.

Since the control is defined by the language, the run-time module does not need modification. And the code “scripts” or routines, which makes adding new actions simple.
I don’t think I understand. So how can I do this if I want to implement this?

I am not doing any robotic stuff btw, I just think this example can explain what I mean, that’s all.
 

djsfantasi

Joined Apr 11, 2010
9,237
Sorry I misunderstood your post. Could you repeat what you would like to do? Forget about potential solutions. Ignore any talk of structures.

Please just state your objectives.
.
 

nsaspook

Joined Aug 27, 2009
16,330
I don’t think I understand. So how can I do this if I want to implement this?

I am not doing any robotic stuff btw, I just think this example can explain what I mean, that’s all.
Not exactly sure what you want to do.
A list of skill ID's (ENUM) and a matching table of skill function pointers in a array that are executed inside a runRobot procedure skill task by skill ID from min ENUM to max ENUM.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Sorry I misunderstood your post. Could you repeat what you would like to do? Forget about potential solutions. Ignore any talk of structures.

Please just state your objectives.
.
Well, I like to know if I can write a function - say runRobot(). This function can take an input that has a list of skills (structures), and these skill contains the data and methods about what to do and how to implement this new skill.

something like this:
Code:
Robot_t robotA = createRobot();                           /* create a robot A with basic skills        */
Robot_t robotB = createRobot();                           /* create a robot B with basic skills        */
Skill_fly_t skill_fly = createSkillFly();                        /* create a special skill - fly                */
Skill_swim_t skill_swim = createSkillSwim();           /* create a special skill - swim            */

robotA.addSkill(skill_fly);
robotB.addSkill(skill_swim);

/*!
*     runRobot() has no knowledge of different new
*     skills. The new skill has some kind information
*     to tell runRobot() how to implement this new
*     skill.
*/
runRobot(robotA);    /* this robot now can fly    */
runRobot(robotB);    /* this robot now can swim    */
Hope it makes more sense now?
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Not exactly sure what you want to do.
A list of skill ID's (ENUM) and a matching table of skill function pointers in a array that are executed inside a runRobot procedure skill task by skill ID from min ENUM to max ENUM.
Oh yeah, that's one way. Now you make me think...
 

djsfantasi

Joined Apr 11, 2010
9,237
I think I understand better. But I still think you are putting the cart before the horse, as they say.

You want to execute different code/skill based on an object it is passed.

That’s it, right?

An extension might be to execute one of many skills based on an object it is passed and some sort of skill identifier.

But I’m muddying up my post. Back to this statement...

You want to execute different code/skill based on an object it is passed.

Right?
 

BobaMosfet

Joined Jul 1, 2009
2,211
@bug13-

Yes, you can do this, but you have to know how. In fact, this sort of thing is frequently used in order to move data through O/S's, from one internal aspect to another. It is a very powerful technique if properly used.

You, and only you understand the shape and form of your data. The compiler only cares about what the linker needs- address of memory block, and offsets to its fields in order to access its elements correctly.

Code:
typedef struct
   {
   int  value1;
   int  value2;
   char   value3;
   }robot_obj;

typedef struct
   {
   robot_obj   robot;
   int   booster;
   int   maxspeed;
   int   steering;
   }skill_fly;

robot_obj   *myRobot;
The way you do this is that your program originally malloc()'s myRobot; That gives you a pointer to a memory block that matches your robot_obj structure. Later, if you want to add the ability to fly, you take myRobot and realloc() it as a skill_fly. Because it's dynamically allocated, the program logic does not change. Everything that references robot_obj still works, because everything is still in the same place in the reallocated memory block. Anything that references the skill_fly aspect, merely now coerces the robot_obj to the appropriate pointer type (coercion just tells the linker you want to look at something differently).

Code:
int  speed;

speed = ((skill_fly*)myRobot)->maxspeed;
I hope that makes sense. Remember, if you want to do objects in C, _you_ not the compiler have to manage the mechanics to make it work.
 

xox

Joined Sep 8, 2017
936
Hi team

Say we have a function that run a robot - runRobot(), and it take a robot structure, and this structure contains necessary information for runRobot() to do stuff:

Code:
typedef struct ROBOT_OBJ{
    uint8_t health;
    uint8_t attack;
    uint8_t block;
}robot_obj_s;

robot_obj_s simple_robot;

runRobot(simple_robot)
Say I want to add a special skill to this robot, and I define a structure for special skill like this:
Code:
typedef struct SKILL_FLY{
    uint8_t max_speed;
    uint8_t booster;
    uint8_t steering;
    ...
}skill_fly_s;
And I want to be able to add to my robot by simply adding the new skill to the robot structure without modifying my runRobot() code like this:
Code:
[CODE]typedef struct ROBOT_OBJ{
    uint8_t health;
    uint8_t attack;
    uint8_t block;
    skill_fly_s skill_fly;        /* added new skill    */
}robot_obj_s;

robot_obj_s simple_robot;

/*!
*    my runRobot() function can regonizse this new skill
*    without me rewritting the runRobot() function
*/
runRobot(simple_robot)
What problem are you really trying to solve here? Just how dynamic you want to get is up to you, but remember, it usually comes at a price. Macros, complex API interactions, debugging. If it's just as easy to modify the code directly then save youself the hassle. But if you really do need dynamic behavior, like at the runtime level, then maybe a scripting language might be a better choice.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
[/QUOTE]
You want to execute different code/skill based on an object it is passed.
Yes, but the object is the same object with added skills (one or more).
eg:
Code:
/*!
*     Add skills to robotA, these skills are unknow
*     robotRun(). They can be design by different
*     people by following some pre-define rules and
*     structures.
*/
robotA.addSkill(fly);
robotA.addSkill(swim);
robotA.addSkill(dance);

/* Add skill to robotB */
robotB.addSkill(fly);

/* robot A can fly, swim and dance     */
runRobot(robatA);

/* robot B can fly only */
runRobot(robatB);
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
@bug13-

Yes, you can do this, but you have to know how. In fact, this sort of thing is frequently used in order to move data through O/S's, from one internal aspect to another. It is a very powerful technique if properly used.

You, and only you understand the shape and form of your data. The compiler only cares about what the linker needs- address of memory block, and offsets to its fields in order to access its elements correctly.

Code:
typedef struct
   {
   int  value1;
   int  value2;
   char   value3;
   }robot_obj;

typedef struct
   {
   robot_obj   robot;
   int   booster;
   int   maxspeed;
   int   steering;
   }skill_fly;

robot_obj   *myRobot;
The way you do this is that your program originally malloc()'s myRobot; That gives you a pointer to a memory block that matches your robot_obj structure. Later, if you want to add the ability to fly, you take myRobot and realloc() it as a skill_fly. Because it's dynamically allocated, the program logic does not change. Everything that references robot_obj still works, because everything is still in the same place in the reallocated memory block. Anything that references the skill_fly aspect, merely now coerces the robot_obj to the appropriate pointer type (coercion just tells the linker you want to look at something differently).

Code:
int  speed;
speed = ((skill_fly*)myRobot)->maxspeed;
I hope that makes sense. Remember, if you want to do objects in C, _you_ not the compiler have to manage the mechanics to make it work.
I think I sort of understand it.

Just to make thing simply, say all variables are one byte, so you get:
Code:
typedef struct
{
           int  value1;      /* one byte */
           int  value2;      /* one byte */
           char value3;      /* one byte */
}robot_obj;

/* this robot_obj will take 3 bytes im memory */

typedef struct
{
   robot_obj   robot;      /*  3 bytes */
   int   booster;          /*  1 byte  */
   int   maxspeed;         /*  1 byte  */
   int   steering;         /*  1 byte  */
}skill_fly;

/* this skill fly will take 6 bytes in total */
when a robot_obj* pointer is cast to skill_fly*, the first 3 bytes pointer offset are the same (overlap in memory), and the new myRobot* pointer can access whatever below robot_obj in the skill_fly correct?
Code:
 myRobot pointer    skill_fly pointer
->value1                     ->value1
->value2                     ->value2
->value3                     ->value3
                             ->booster
                             ->maxspeed
                             ->steering
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
What problem are you really trying to solve here? Just how dynamic you want to get is up to you, but remember, it usually comes at a price. Macros, complex API interactions, debugging. If it's just as easy to modify the code directly then save youself the hassle. But if you really do need dynamic behavior, like at the runtime level, then maybe a scripting language might be a better choice.
I wasn't trying to solve anything for now. It's Xmas break, it's one of my many random thoughts that I think maybe useful, or at least it's very interesting (to me).

But what scripting language are you referring to?
But if you really do need dynamic behavior, like at the runtime level, then maybe a scripting language might be a better choice.
 

BobaMosfet

Joined Jul 1, 2009
2,211
I think I sort of understand it.

Just to make thing simply, say all variables are one byte, so you get:
Code:
typedef struct
{
           int  value1;      /* one byte */
           int  value2;      /* one byte */
           char value3;      /* one byte */
}robot_obj;

/* this robot_obj will take 3 bytes im memory */

typedef struct
{
   robot_obj   robot;      /*  3 bytes */
   int   booster;          /*  1 byte  */
   int   maxspeed;         /*  1 byte  */
   int   steering;         /*  1 byte  */
}skill_fly;

/* this skill fly will take 6 bytes in total */
when a robot_obj* pointer is cast to skill_fly*, the first 3 bytes pointer offset are the same (overlap in memory), and the new myRobot* pointer can access whatever below robot_obj in the skill_fly correct?
Code:
myRobot pointer    skill_fly pointer
->value1                     ->value1
->value2                     ->value2
->value3                     ->value3
                             ->booster
                             ->maxspeed
                             ->steering
Yes, you understand. *THIS* is how this sort of thing is done in C, for structures. This allows you to alter the structure and expand a capability, WITHOUT modifying existing code, so long as the existing code does not rely on the original size of the structure.
 

BobTPH

Joined Jun 5, 2013
11,533
I think what you really want is an object oriented language like C++.

In an object oriented language, you would define a base object type (class in C++ terms) that contained the code for all the basic operations, and has a method called run().

When you want to make a flying robot, you would create a new class with robot as its base and add the code for the flying skill. It would the have all the capabilities of robot and the additional skill of flying.

Bob
 

nsaspook

Joined Aug 27, 2009
16,330
I think what you really want is an object oriented language like C++.

In an object oriented language, you would define a base object type (class in C++ terms) that contained the code for all the basic operations, and has a method called run().

When you want to make a flying robot, you would create a new class with robot as its base and add the code for the flying skill. It would the have all the capabilities of robot and the additional skill of flying.

Bob
The problem with using C++ inheritance here as in most problems is the want Banana get Jungle problem. Do you really need it? Unrestrained OOP (paradigm abstraction) is evil IMO when you are writing all the code.
https://www.tedinski.com/2018/02/13/inheritance-modularity.html
This relatively simple concept scales up, and hits us hard. Too many OO books start with some uselessly dumb example of inheritance (“car extends vehicle” is the punch line of a joke at this point). Nearly all of these are heinously terrible designs.
 
Last edited:

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Yes, you understand. *THIS* is how this sort of thing is done in C, for structures. This allows you to alter the structure and expand a capability, WITHOUT modifying existing code, so long as the existing code does not rely on the original size of the structure.
I find this technique very interesting. Now I remember in the TI-RTOS, they use the same technique to implement QUEUE (link).

What else can I use this for? Can you give one or two example?
 
Top