0

I don't really know how to explain this.

I have 2 classes World and Entity in the namespace:

artemis::system;

and one class Component in

artemis::component;

I already had trouble with World and Entity, when trying compile it said either one of them wasn't a declared type. ( they both include each other) So in both classes, within the the namespace, I've added a forward declaration. This seems to solve the problem.

Now when I try to include "world" in my Component.h it gives me the following error:

component is not a namespace-name

My Component class resides within the namespace artemis::component.

This is driving me crazy. I really don't get what is causing this error.

Header Component.h

#ifndef _COMPONENT_H_
#define _COMPONENT_H_

#include <bitset>
#include "BitSize.h"
#include "World.h"
#include <unordered_map>
#include <typeinfo>
#include <string>
#include <iostream>
#include <assert.h>
//#include "EntityManager.h"

using namespace std;
using namespace artemis::system;

namespace artemis {
    namespace component {


        class Component {
            public:
                virtual ~Component() = 0;
            protected:
                Component(){};
        };


        /**
         * Identifies a bitset and id for a component object
         * Do not instantiate a ComponentType, instead use the ComponentTypeManager.
         * */
        class ComponentType {

            public:
                ComponentType();

                bitset<BITSIZE> getBit() const;
                int getId() const;
            private:

                static bitset<BITSIZE> nextBit;
                static int nextId;

                bitset<BITSIZE> bit;
                int id;
                void init();

        };


//Surpress unused variable warnning. Might need to rewrite it
//#pragma GCC diagnostic push
//#pragma GCC diagnostic ignored  "-Wunused-variable"
        /**
         * Manages the id and bitset for every component based on their type.
         * */

        class ComponentTypeManager {

            private:
                ComponentTypeManager();
                static unordered_map<size_t,ComponentType*> componentTypes;



        public:


                /**
                 *
                 **/
                static ComponentType & getTypeFor(const type_info &t);

                /**
                * Gets the component type object
                **/
                template<typename c>
                static ComponentType & getTypeFor() {

                    //Check if we are being legal with components and shizzle
                    //Component * c = (component*)0;

                    assert((std::is_base_of< Component, c >::value == true));

                    return getTypeFor(typeid(c));
                }

                /**
                * Gets the bit set of a component
                **/
                template<typename c>
                static bitset<BITSIZE> getBit() {

                    //Check if we are being legal with components and shizzle
                    //Component * c = (component*)0;

                    assert((std::is_base_of< Component, c >::value == true));

                    ComponentType & type = getTypeFor(typeid(c));
                    return type.getBit();
                }
                /**
                 * Gets the component id
                 **/
                template<typename c>
                static int getId() {

                    //Check if we are being legal with components and shizzle

                    assert((std::is_base_of< Component, c >::value == true));

                    ComponentType & type = getTypeFor(typeid(c));
                    return type.getId();
                };



                //typedef getCompBit bitset<BITSIZE>(*getBit<Component>)();

        };
//#pragma GCC diagnostic pop




        /*template<typename T>
        class ComponentMapper {

            private:
                //ComponentType * type;
                EntityManager * em;

            public:

                ComponentMapper(World &world) {
                    em = world.getEntityManager();
                    //type = ComponentTypeManager::getTypeFor<T>();
                }

                ~ComponentType() {
                    type = nullptr;
                    em = nullptr;
                }

                T & get(Entity * e) {
                    return &(T)em->getComponent<T>(e);
                }

        };*/

    };
};

#endif

Header Entity.h

#ifndef _ENTITY_H
#define _ENTITY_H

#include <bitset>
#include <string>
#include <cstddef>
#include <typeinfo>
#include "BitSize.h"
#include "Component.h"
#include "ImmutableBag.h"
#include "World.h"
//#include "EntityManager.h"

using namespace artemis::util;
using namespace artemis::component;
//using namespace artemis;
using namespace std;



namespace artemis {
    namespace system {
        class World;
        class Entity {

            private:
                int id;
                long int uniqueId;
                bitset<BITSIZE> typeBits;
                bitset<BITSIZE> systemBits;
                World * world;
                //EntityManager * entityManager;
            protected:

            public:
                Entity(World * world, int id);
                ~Entity();
                int getID();
                void setUniqueId(long int uniqueId);
                long int getUniqueID();

                bitset<BITSIZE> getTypeBits();
                void addTypeBit(bitset<BITSIZE> bit);
                void removeTypeBit(bitset<BITSIZE> bit);
                bitset<BITSIZE> getSystemBits();
                void addSystemBit(bitset<BITSIZE> bit);
                void removeSystemBit(bitset<BITSIZE> bit);
                void setSystemBits(bitset<BITSIZE> systemBits);
                void setTypeBits(bitset<BITSIZE> typeBits);
                void reset();

                string toString();

                void addComponent(Component * c);

                //Might change to non template
                template<typename c>
                void removeComponent() {
                    //entityManager->removeComponent(this,ComponentTypeManager::getTypeFor<c>());
                }

                void removeComponent(ComponentType & type);
                bool isActive();

                Component * getComponent(ComponentType & type);

                /*template<typename c>
                Component * getComponent() {
                    return (c)entityManager->getComponent(ComponentTypeManager.getTypeFor<c>());
                }*/

                ImmutableBag<Component*> * getComponents();
                void refresh();
                void remove();
                void setGroup(string group);
                void setTag(string tag);


        };
    };
};
#endif // $(Guard token)

Header World.h

#ifndef _WORLD_H_
#define _WORLD_H_

//#include "SystemManager.h"
//#include "EntityManager.h"
#include "ImmutableBag.h"
#include "Entity.h"

using namespace artemis::util;



namespace artemis {
    namespace system {

    class Entity;

        class World {
            public:
                World();
                ~World();
                //SystemManager * getSystemManager();
                //EntityManager * getEntityManager();
                //TagManager *   getTagManager();
                //GroupManager * getGroupManager();
                int getDelta();
                void setDetla(int delta);
                void deleteEntity(Entity *e);
                void refreshEntity(Entity *e);
                //Entity* createEntity();
                //Entity* getEntity(int entityID);
                void loopStart();



            private:
                //SystemManager * systemManager;
                //EntityManager * entityManager;
                //TagManager * tagManager;
                //GroupManager * grouManager;
                int delta;
                Bag<Entity*> refreshed;
                Bag<Entity*> deleted;



        };
    };
};
#endif // $(Guard token)
Sidar
  • 504
  • 1
  • 9
  • 28
  • What do you mean by testcase? – Sidar Jul 02 '12 at 23:30
  • Sounds like you are confusing a namespace with the type name. Is component *actually* a namespace or is it a type? – Ed S. Jul 02 '12 at 23:32
  • Testcase is what I mean by testcase... Google would tell you what that means, as well as http://sscce.org/... – Griwes Jul 02 '12 at 23:32
  • @EdS. I've teste Component before I created the World and entity class. I had no trouble with the namespace component. Are capitals ignored? – Sidar Jul 02 '12 at 23:34
  • "*when trying compile it said either one of them wasn't a declared type. ( they both include each other)*" Sounds like a circular inclusion problem, not a namespace problem. Show us your header files. – ildjarn Jul 02 '12 at 23:35
  • I've added the headers. Runs fine if I take out the "World.h" from Component.h – Sidar Jul 02 '12 at 23:39
  • `Component.h` includes `World.h`, `World.h` includes `Entity.h`, `Entity.h` includes `Component.h` and `World.h` -- _that_ is your problem, not namespaces. Read up on forward declarations and get rid of the circular inclusion. – ildjarn Jul 02 '12 at 23:42
  • fyi, it's usually not a good idea to put a `using namespace ...;` statement in a header file. – Turix Jul 02 '12 at 23:42
  • It's also a bad idea to use reserved names for include guards. – Mike Seymour Jul 02 '12 at 23:47
  • @MikeSeymour which names are reserved? – Sidar Jul 02 '12 at 23:53
  • 1
    @Sidar: Anything that begins with an underscore followed by a capital letter, or that contains a double underscore; also, anything in the global namespace that begins with an underscore. So `_COMPONENT_H_` shouldn't begin with `_`. See [here](http://stackoverflow.com/q/228783/204847) for full details, and [here](http://stackoverflow.com/q/3345159/204847) for an example of what might go wrong if you break the rules. – Mike Seymour Jul 02 '12 at 23:58

1 Answers1

1

Your problem is that you require Component to already be defined in order to create World, and you require World to be defined in order to create Component. This is impossible; each one's definition requires the other.

You need to restructure your classes so that you either don't require Component to be defined in World's header, OR you don't require World to be define in Component's header. You can always include them in the .cpp, but not the header. It's a circular inclusion problem. You could also forward-declare one of the classes.

You are essentially saying: I cannot create A unless I have already created B; I cannot create B unless I have already created A. That's impossible, and the compiler is telling you so.

WendiKidd
  • 4,333
  • 4
  • 33
  • 50
  • I figured that much, but they both need eachother. And some types are also used in the header. Wouldn't that go wrong if I put the inclusion in the cpp? NVM. – Sidar Jul 02 '12 at 23:44
  • Yes, it would go wrong. If they are absolutely required in the header, you can forward-declare the classes. Take a look at this link: http://www-subatech.in2p3.fr/~photons/subatech/soft/carnac/CPP-INC-1.shtml – WendiKidd Jul 02 '12 at 23:46