Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 696 697 [698] 699 700 ... 796

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 835048 times)

TheBiggerFish

  • Bay Watcher
  • Somewhere around here.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10455 on: March 19, 2017, 01:44:36 pm »

Why would you do that?!
Logged
Sigtext

It has been determined that Trump is an average unladen swallow travelling northbound at his maximum sustainable speed of -3 Obama-cubits per second in the middle of a class 3 hurricane.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10456 on: March 19, 2017, 01:48:21 pm »

Might be useful for some gamedev situations in the future e.g. storing different structure types. Think about making a unity-style gameobject system, but one with more stuff resolved at compile time in c++. Having a data structure that I can just pack arbitrary structs into without needing to write much code could really speed up development time.

But think of it another way: i can create polymorphic lists with this, but it doesn't require me to add anything to the underlying objects, e.g. I don't have to enforce an inheritance tree: the list class is adding on fake inheritance to let me do that. I can decide to throw ad-hoc objects from a completely different heirarchy into the same storage system.
« Last Edit: March 19, 2017, 02:02:25 pm by Reelya »
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #10457 on: March 19, 2017, 09:36:56 pm »

Python-like lists in C++, haha.
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

Strife26

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10458 on: March 19, 2017, 10:01:26 pm »

Seems like a very useful thing, I'd say.
Logged
Even the avatars expire eventually.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10459 on: March 20, 2017, 02:01:43 am »

I improved type checking, edited the post. Instead of the string compare I rewrote it to work like this:

if (type == Type<float>()) /* do float stuff */

So it's just comparing the static pointers

McTraveller

  • Bay Watcher
  • This text isn't very personal.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10460 on: March 20, 2017, 09:37:36 am »

Why so complex? Just have your list store
Code: [Select]
void * ....  8)

I mean, you've got to have code in there that somehow "knows" what to do with the items you pull out of the list later, right?  Maybe I'm missing how this is different from that?
Logged

lethosor

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10461 on: March 20, 2017, 11:07:16 am »

You wouldn't be able to determine the type of an arbitrary element in the list using void pointers, unless you kept track of each element's type somewhere else, which doesn't seem to be the case here.
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10462 on: March 20, 2017, 12:29:52 pm »

Why so complex? Just have your list store
Code: [Select]
void * ....  8)

I mean, you've got to have code in there that somehow "knows" what to do with the items you pull out of the list later, right?  Maybe I'm missing how this is different from that?

You could use void pointers, but to have the full functionality of what I've written you'd have to write a lot more.

First up, mine was based on that double-linked list code from a few pages ago. Most of that is in fact superfluous to what we're doing here. I got rid of that, split things up and implemented just a basic stack to replace the list:

Code: [Select]
template <typename T> const char* Type() { static const char *s = typeid(T).name(); return s; }

struct nodeBase
{
    nodeBase *next = 0;
    const char *type;
    int size;
    virtual ~nodeBase() {};
    virtual void *Data() = 0;
};

template <typename T> struct node : public nodeBase // template for storing regular structs and stuff
{
    T data;
    node(T _data) : data(_data)
    {
        type = Type<T>();
        size = sizeof(data);
    }
    ~node()    {}
    void *Data() { return &data; }
};

template <> struct node<const char*> : public nodeBase // this is a template specialization just for strings
{
    char *data;
    node(const char *_data)
    {
        type = Type<const char*>();
        size = strlen(_data) + 1;
        data = new char[size];
        strcpy_s(data, size, _data);
    }
    ~node() { delete data; }
    void *Data() { return data; }
};

template <typename T> nodeBase *create(T data) { return new node<T>(data); }
template <> nodeBase *create<std::string>(std::string data) { return create(data.c_str()); }

void displayNode(nodeBase *n)
{
    if (!n) return;

    std::cout << n->type << "( " << n->size << " bytes ) ";

    if (n->type == Type<float>())
    {
        std::cout << " = " << *(float *)(n->Data()) << std::endl;
    }
    else if (n->type == Type<double>())
    {
        std::cout << " = " << *(double *)(n->Data()) << std::endl;
    }
    else if (n->type == Type<char const *>())
    {
        std::cout << " = " << (const char *)n->Data() << std::endl;
    }
    else
    {
        std::cout << " = " << *(int *)n->Data() << std::endl;
    }
}

class stack
{
public:
    nodeBase *head = nullptr;
    unsigned int count;

    ~stack()
    {
        while (head)
        {
            nodeBase *temp = head;
            head = head->next;
            delete temp;
        }
    }

    template <typename T> void push(T data)
    {
        nodeBase *new_node = create(data);
        new_node->next = head;
        head = new_node;
        count++;
    }

    nodeBase *operator[](int index)
    {
        nodeBase *node = head;

        while (index > 0 && node != nullptr)
        {
            node = node->next;
            index--;
        }

        return node;
    }
};

struct Cat { int whiskers = 1000; };

int test_list_multi()
{
    stack list1;

    list1.push(44);
    list1.push(2.0423423432f);
    list1.push("drugs");
    list1.push(std::string("hello"));
    list1.push(bool(true));
    list1.push(2.4545);
    list1.push('a');
    list1.push(short(66));
    list1.push([] { int a, b; });
    list1.push([] { int a; });
    struct Dog { int legs[4]{ 9,9,9,9 }; char tail{ 't' }; };
    Dog dog;
    Cat cat;
    list1.push(dog);
    list1.push(cat);

    std::cout << "count = " << list1.count << std::endl;

    for (int i = 0; i < list1.count; ++i)
    {
        displayNode(list1[i]);
    }

    std::cin.ignore();
    std::cin.get();
    return 0;
}

The "storing anything" code ends at line 39. Another 20 lines is the code to print out the different types, 35 lines is the basic stack implementation for storing stuff, and another 35 lines is the main testing function that creates values then prints them all out. The total of everything here is 135 lines of code.

ok so how exactly are you going to do the same thing with void*? Where do you start? Well the first problem is that you have to be able to pass an "int" in to be stored. So you need a "StoreInt" function. Then you might want to store bools so you need a "storeBool" function. Don't forget your "StoreShort", "Store unsigned int" "Store long" etc etc. So you might decide that instead of that, you pass in a void pointer to the item. Don't forget to cast that pointer to void* when you're calling. And also pass in the sizeof value, and some information on the type. Can't forget that ;D
« Last Edit: March 20, 2017, 01:55:31 pm by Reelya »
Logged

i2amroy

  • Bay Watcher
  • Cats, ruling the world one dwarf at a time
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10463 on: March 20, 2017, 07:11:36 pm »

IIRC any pointer can be cast behind the scenes automatically to a void pointer, so literally you would just need a single "store" function that you passed &var to, with whatever code called the store or retrieve functions being responsible for knowing what to cast it back to (so no need to store size either). It would be horribly unsafe and remarkably fragile, but that's a general rule for the "C" way of doing things anyways. :P
Logged
Quote from: PTTG
It would be brutally difficult and probably won't work. In other words, it's absolutely dwarven!
Cataclysm: Dark Days Ahead - A fun zombie survival rougelike that I'm dev-ing for.

itisnotlogical

  • Bay Watcher
  • might be dat boi
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10464 on: March 20, 2017, 10:55:22 pm »

I received the Raspberry Pi for the STEM club's ballooning project, just to play with it and get used to it. Installed Python 3 and a GPIO module named RPi.GPIO and wait why is there a period in the module name

Even if it's technically allowed, why? Why, you madmen? You literally have to import it under an alias that doesn't have a period or else it will be impossible to use.

There's another GPIO module out there and I could use another language altogether, one that might be more supported, but all the same

it begins
Logged
This game is Curtain Fire Shooting Game.
Girls do their best now and are preparing. Please watch warmly until it is ready.

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #10465 on: March 20, 2017, 11:06:22 pm »

I hate typical 'clever' C code like this:

Code: [Select]
char *first_word(char *str){
 char *m;
 int s,l,i;
 for(s=0;str[s]==' '; s++);
 for(length = 0; str[s+l]!=' '&&str[s+l]!='\0'; l++);
 m = malloc((l+1)*sizeof(char));
 for (i=0; i<l; i++)
  m[i] = str[s+i];
 m[l] = '\0';
 return m;
}

The first for loop, especially.
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10466 on: March 21, 2017, 12:16:36 am »

IIRC any pointer can be cast behind the scenes automatically to a void pointer, so literally you would just need a single "store" function that you passed &var to, with whatever code called the store or retrieve functions being responsible for knowing what to cast it back to (so no need to store size either). It would be horribly unsafe and remarkably fragile, but that's a general rule for the "C" way of doing things anyways. :P

But the problem is that if you only send a void pointer then the receiving function has in fact no way of knowing what you sent to it. Let's consider the function you'd have to write:

void store(void *myThing) {}

How does "store" know what myThing really was? So you'd have to send it extra information:

void store(void *myThing, enum myType, enum mySize) {}

And that would ensure that you need a full catalogue of all possible types in your enum before you start using this, and you'd have to call it like this:

int whatToStore;

store((void *)whatToStore, typeInt, sizeof(int));

And to get around the need for doing this, you'd have to write a template function, which is exactly what I already did. And if you have a template function, there's no need to cast to void*.
« Last Edit: March 21, 2017, 12:20:44 am by Reelya »
Logged

Strife26

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10467 on: March 21, 2017, 12:25:27 am »

I hate typical 'clever' C code like this:

Code: [Select]
char *first_word(char *str){
 char *m;
 int s,l,i;
 for(s=0;str[s]==' '; s++);
 for(length = 0; str[s+l]!=' '&&str[s+l]!='\0'; l++);
 m = malloc((l+1)*sizeof(char));
 for (i=0; i<l; i++)
  m[i] = str[s+i];
 m[l] = '\0';
 return m;
}

The first for loop, especially.

Yep. I have no desire to try to decipher that. I mean, I ain't anything good yet, but code with more white space seems superior to me.
Logged
Even the avatars expire eventually.

itisnotlogical

  • Bay Watcher
  • might be dat boi
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10468 on: March 21, 2017, 12:33:40 am »

Nonsense, your code is only "clean" and "elegant" if you use single-letter names for every variable. Words are for scrubs. Abbreviations are acceptable only if you can't tell what the original word was.
Logged
This game is Curtain Fire Shooting Game.
Girls do their best now and are preparing. Please watch warmly until it is ready.

Rose

  • Bay Watcher
  • Resident Elf
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #10469 on: March 21, 2017, 12:50:43 am »

the first for loop is easy. It just goes through the string letter by letter until it finds a space. then s is the index of that space.
Logged
Pages: 1 ... 696 697 [698] 699 700 ... 796