Jump to content

  • Log In with Google      Sign In   
  • Create Account


Juliean

Member Since 29 Jun 2010
Online Last Active Today, 10:32 AM
-----

Topics I've Started

Handling information delivery in editor mode

Today, 07:30 AM

Hello,

 

I'm currently working deeply on my editor. As things are starting to get more complex, I often end up in a situation where the amount of, lets call it information handling, of my code is not good enough for some editor features. I have, for example, a visual scripting system, much like the one used in Unreal4. In each such visual script, I can have a number of variables, and like in Unity, all variables marked "public" can be seen and modified from outside. I also have an entity component system, where I have a specific component for attaching a visual script to the entity.

This component should show and allow to modify all public variables. As for this, it currently has a map<string, string>, whose values are written to the visual scripts variables, and also serialized. This is how the class looks:

		class Event :
			public ecs::Component<Event>
		{
		public:

			Event(void);
			Event(const std::wstring& stName);
			~Event(void);

			std::wstring stName;
			core::EventInstance* pInstance;
			std::map<std::wstring, std::wstring> mVariables;

			static const ecs::ComponentDeclaration& GenerateDeclaration(void);
		};

Whenever the name of the visual script (here called "event") is set (thats what the stName-variable is for), the component gets notified via callback and is allowed to query the scripts variables and modify the map accordingly. That part works so far.

 

However, what I don't know how to make work, is what happens when a variable is modified in the visual script. How am I supposed to deliver that information to wherever it is needed in the editor? Don't get me wrong, I know how to transfer such events, via messaging, callbacks, signals... but my question is rather, how I could do this in an efficient and architecturally nice way. The thing is, I don't simply want to add a signal for everything to the class like that:

class EventInstance
{
public:
    
    // ...

    core::Signal<const EventVariable&> SigVariableAdded;
    core::Signal<const std::wstring&> SigVariableRemoved;
    core::Signal<const EventVariable&> SigVariableTypeChanged;

    // ...
}

For the reason being, that I really only every need this for the editor, and the classes here are shared between editor and game. I have a common DLLs that both editor and "player" use, as well as a few plugins that are equally shared. I'm very hasitating to add stuff that is only every needed for that very aspect of "live-feedback" in the editor, which wastes resources and runtime in case of the game, where it is simply not needed. I also don't want to rewrite my classes just for the editor...

 

So what I'm looking for is basically a way to implement such information exchanging for the editor on top of the already existing classes. To put it in a answerable question: How would/did you implement such a thing in an editor? I'm glad for any suggestion, I have a few things in mind, but I don't want to bias anyone. Note that this is just an example, that thing actually happens in a lot of places, so I hope you can help me out without me having to show too much code, but if you need to see something more of the architecture, let me know.


Storing position of member variable

14 July 2014 - 04:23 AM

Hello,

 

I know that there is no such thing like reflection in C++, but I need something a tad bit in that direction. I want to refactor and improve my component system, by automating most loading/serialization/editor-related stuff. For this, I plan on adding a component declaration class, where attributes with a certain known type (int, float, string, ...) are specified. This would look something like that:

class Transform : public ecs::Component<Transform>
{
	math::Vector3 vPosition;
	
	static const ComponentDeclaration& Declaration(void)
	{
		const ComponentDeclaration::AttributeVector vAttributes = 
		{
			{ AttributeType::FLOAT, "x" },
			{ AttributeType::FLOAT, "y" },
			{ AttributeType::FLOAT, "z" },
		}
		
		static const ComponentDeclaration decl(vAttributes);
		
		return decl;
	}
}

Now, I just could have a "serialize/deserialize"-method, but I want to ultimately get rid of those, to minimize work required for each component. Is there any way to calculate/store the "offset" of a member variable and use this to access/set that variable? Something like:

// in the declaration

{ AttributeType::FLOAT, "x", OFFSET(Component::vPosition::x) },

// later on

auto& component = ComponentFactory::CreateComponent(type);

const auto& declaration = component.GetDeclaration();

for(auto& attribute : declaration.GetAttributes())
{
	switch(type)
	{
	case AttributeType::FLOAT:
	{
		float* pAttribute = (float*)(((char*)(void*)(component)) + attribute.offset);
	}
	}
}

How would you do so?

 

PS: Though I don't care about 100% (type)safety and cross-compiler right now, I'm also open for all other, probably better suggestions for that problem you might have.


Refactoring if-conditions for player turn code

10 June 2014 - 01:08 PM

Hello,

 

I've got some code for a 2d game that orients an NPCs graphic towards the direction he is walking to. There are 4 directions (down, left, right, up), that have the values (0, 1, 2, 3) respectively (so 3 - direction will yield the other direction on that axis). It is possible for the NPC to walk straight, diagonally, and unevenly-diagonally (2 pixel on the x-axis, 1 on the y-axis, hope you know what I'm talking about). Now the code for mapping this movement to the direction is rather clumsy, just a big mess of if-statements:

unsigned int DirectionFromMove(const math::Vector2& vMove)
{
	if(vDir.x > 0)
	{
		if(vDir.y > 0)
		{
			if(vDir.x > vDir.y)
				return 2;
			else
				return 0;
		}
		else if(vDir.y < 0)
		{
			if(vDir.x > abs(vDir.y))
				return 2;
			else
				return 3;
		}
		else
			return 2;
	}
	else if(vDir.x < 0)
	{
		if(vDir.y > 0)
		{
			if(abs(vDir.x) > vDir.y)
				return 1;
			else
				return 0;
		}
		else if(vDir.y < 0)
		{
			if(vDir.x < vDir.y)
				return 1;
			else
				return 3;
		}
		else
			return 1;
	}
	else
	{
		if(vDir.y > 0)
			return 3;
		else if(vDir.y < 0)
			return 0;
	}
}

I thought about it for a while, but didn't find any better way myself. I'm really curious, since in "production"-code I always end up with stuff like this. Is there some clever solution here to get rid of all the ifs?


Reading/Writing UTF8 with filestreams

30 May 2014 - 08:35 AM

Hello,

 

I've just recently come across the problem that I cannot load certain vowels like ä, ü, ö from my xml-files. I'm using a std::wfstream, so how do I configure it to load those characters? (when I load it now, I always get 2 nonsense-chars from the one supposed-to-be widechar).

 

I tried:

std::wfstream m_stream;

std::locale locale("");
m_stream.imbue(locale);

m_stream.open(stFilename.c_str(), std::ios::in);

but it doesn't work, regardless of whether I open the stream before or after, even though my machine is set to german. Any ideas?


Multiple inheritance and casting

29 May 2014 - 05:41 PM

Hello,

 

I have a very specific problem. I recently refactored my visual scripting system, now I have 4 types of component-classes: Input, Output, Attributes, and Return, for all the possible slots that a command could have. There is also a base EventCommand-class. I know its probably not good style, but in order to form a type of command, a middle-class is constructed by deriving from the EventCommand-class and every component that the command-type should have. Now, most code dealing with those EventCommands is written generically, by dealing with the mentioned components. For that matter, the EventCommand-class has methods for querying each Component, returning nullptr in case it is not found, otherwise it returns a pointer to the component casted from the "this"-pointer of the event-command-class. Thats where my problems begin.

 

I used to wrote this cast like this:

s ACCLIMATE_API EventCommand
{
public:

    InputComponent* QueryInput(void);
    OutputComponent* QueryOutput(void);
    AttributeComponent* QueryAttribute(void);
    ReturnComponent* QueryReturn(void);

private:

    // is called by the above 4 methods
    template<typename ComponentType>
    ComponentType* ComponentCast(SlotType type)
    {
        if(m_slots & type)
        {
#ifdef _DEBUG
            return dynamic_cast<ComponentType*>(this);
#else
            return (ComponentType*)this;
#endif
        }
        else
            return nullptr;
    }
    
    unsigned int slotTypes;
}

Since I aimed for optimal performance and generally try to avoid dynamic_cast where possibly without making my architecture needlessy complicated, I wrote the code so that it would dynamic_cast in debug build to ensure that the component is actually a child, and in release builds would just static-cast it. I've spent the last 2 hours, since I just tried to run it in release, trying to find the cause for a unspecific crash in the application, until I stumbled over this by accident. Via google, I found out that you are actually required to use dynamic_cast with multiple inheritance... so this leads to my questions:

 

- How bad is dynamic_cast in terms of performance anyway? I tried to search e.g. stackoverflow, but most answers are eigther very generic or too old, I'd like to know how the situation looks nowadays. Yeah I know, performance is realitiv and measuring just this one component is not going to say much, also feel free to hit me for optimizing prematurely, but I'd still like to hear what you've found out in your experience.

 

- Since I already have type information myself (I need those for some other parts anyway), is there any better way of handling this without dynamic casting? This is probably depending on the answer to the above questions... Yeah, the type-information its not 100% safe. Its just an enum:

		enum SlotType
		{
			INPUT = 1, 
			OUTPUT = 2, 
			ATTRIBUTE = 4, 
			RETURN = 8
		};

So bogus values could be passed, but it is pretty much a controlled environment, and in debug it will complain anyways. Is there probably even some safer way for handling this kind of type information at compile-time rather than having to perform needless runtime checks? I'm mainly asking because the available child classes are already known and very limitied, so I quess there could at least be an alternative to dynamic_cast which seems to be mostly made for the case where your parent class could be anything. What would you do here?

 


PARTNERS