Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syncing data between objects #623

Closed
JoshKlint opened this issue Apr 7, 2018 · 3 comments
Closed

Syncing data between objects #623

JoshKlint opened this issue Apr 7, 2018 · 3 comments
Assignees
Milestone

Comments

@JoshKlint
Copy link

JoshKlint commented Apr 7, 2018

This is not a sol question, but the design of your API gave me this idea and I thought you might be able to point me in the right direction.

I am working on a new multithreaded renderer. An object that lives on the game logic side has a simplified object that lives in the rendering thread, and represents the object's relevant rendering info. For example, a visible entity would have a RenderObject associated with it in the rendering thread. When the entity moves, the RenderObject's 4x4 matrix gets updated when the threads sync.

I am thinking about implementing a list of commands for the rendering thread. This would work by accepting a pointer to a class member and a value, or a pointer to a class method:

class Entity
{
    shared_ptr<RenderObject> renderobject;
    Vec4 color;

    void SetColor(const float r, const float g, const float b, const float a)
    {
        //Set the color
        this->color = Vec4(r,g,b,a);

        //Now add an instruction that will update the corresponding object when the threads sync:
        commandqueue.AddInstruction( this->renderobject, &RenderObject::color, this->color ); //Object, pointer to member, new value
    }
};

Some instructions might call a method instead, along with the function arguments:

commandqueue.AddInstruction( this->renderobject, &RenderObject::SetColor, r, g, b, a ); //Object, pointer to method, arguments

The point of this is to avoid writing a thousand switch/case statements for all the different values and functions. This is what I want:

for each instruction {
    instruction.o->(*instruction.member) = instruction.value;
}

This is what I want to avoid doing:

for each instruction {
    switch (instruction.id)
    {
        case INSTRUCTION_MODIFY_ENTITY_COLOR:
            dynamic_pointer_cast<RenderObject>(instruction.object)->color = (Vec4)instruction.value;
            break;
    }
}

Can you suggest how I might go about this? I have only done very basic work with templates. Any advice you have would be appreciated.

@ThePhD
Copy link
Owner

ThePhD commented Apr 7, 2018

Did you mean to close the issue, or was that a mistake...?

@ThePhD ThePhD reopened this Apr 7, 2018
@ThePhD ThePhD added this to the Helpdesk milestone Apr 7, 2018
@ThePhD
Copy link
Owner

ThePhD commented Apr 7, 2018

Either way, your goal here sort of goes beyond the scope of sol2. This is a C++ thing, and figuring out how to shadow and/or propogate changes -- with thread safety -- is not necessarily my wheelhouse. I would expect that you'd need to something like store a std::function-alike that just runs some arbitrary code so you don't have to think about what it's actually doing, then invoke it with for each instruction { instruction(); }

@ThePhD ThePhD self-assigned this Apr 7, 2018
@JoshKlint
Copy link
Author

Yes, this has nothing to do with sol. I just thought you might know the answer, and did not know another way to ask.

I did get this working by the way, and it is nice and simple:

	class Foo
	{
		int num = 1;
	public:

		void Print()
		{
			printf("%d\n",num);
		}

		void Add(int n)
		{
			num += n;
		}
	};

	std::vector<std::function<void()> > commandbuffer;

	auto f = make_shared<Foo>();

	commandbuffer.push_back(std::bind(&Foo::Add, f, 1));
	commandbuffer.push_back(std::bind(&Foo::Print, f));
	commandbuffer.push_back(std::bind(&Foo::Add, f, 36));
	commandbuffer.push_back(std::bind(&Foo::Print, f));
	commandbuffer.push_back(std::bind(&Foo::Print, f));

	for (int n = 0; n < commandbuffer.size(); ++n)
	{
		commandbuffer[n]();
	}

Output:

2
38
38

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants