• Welcome to World Machine Community. Please login or sign up.
October 15, 2019, 09:59:33 am


Read the Development Diary for an inside look at World Machine's progress!

Post reply

The message has the following error or errors that must be corrected before continuing:
Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.
Note: this post will not display until it's been approved by a moderator.
Other options
Please leave this box empty:
Type the letters shown in the picture
Listen to the letters / Request another image

Type the letters shown in the picture:

Shortcuts: ALT+S save/post or ALT+P preview

Topic summary

Posted by skylerd
 - March 28, 2013, 02:09:44 pm
Thank you so much Stephen! Hopefully I haven't annoyed you too much with all these questions. The Falsify + PreviewWorld works a dream (for now, I'm ignoring thread safety and will be telling my users that they can only update values in WM when they're not doing something in its UI/building). My project is working great, so I'm very thankful for all your help.
Posted by Stephen
 - March 28, 2013, 01:55:56 pm
2.3 Final is imminent -- planning on releasing it later today -- so there is no possibility of getting a callback handler implemented in that. Looking further along, there are a few things that I want to do that will require an asynchronous mechanism -- so this is something that will be on the table soon.

How to tell if your device is actually in the world: Check your GetWorld() member function return; if its null, the device has not actually been placed into the world. Note that all devices are first created then placed into a world.

To send a parameter packet you'll have to create one:

Both ScalarPacket and ParamPacket are defined in ParamPacket.h.

To create one call:

ParamPointer val = PARAM(WMGetPacket(WMP_parameter));

And store it just like any other packet in your output function.

Finally, regarding falsify/preview:

Typically, the WM graph changes only from either world events or device UI changes. When a device UI is showing, WM will generate single-device previews as you change parameters -- this is done by calling Device::Preview(). If your changes are accepted, the framework then falsifies the network from that device, then rebuilds the whole world.

To replicate this at other times, do the same: 1) Call Falsify() to mark this and all following devices as needing a rebuild, then 2) call WorldMachine::core->app->PreviewWorld(world) where world is the world returned from your device's GetWorld().
Posted by skylerd
 - March 28, 2013, 01:25:27 pm
And another question - calling falsify toggles all the icons beside the items to red, but doesn't actually trigger a build of those items. Any further suggestions for triggering the update of them?

EDIT: I'm ignoring thread safety for now (I know, it's bad), and mainly looking for anything that will cause a re-trigger of the graph preview without any user input. PreviewWorld also doesn't seem to update the display properly; I have to manually enable/disable the device to get the changes propagated through the graph.
Posted by skylerd
 - March 28, 2013, 10:59:07 am
I'm looking to store the values out now in my activate function. Where should I be getting a ParamPacket from? Do I need to grab it from the targetted device? Do I create a new one?
Posted by skylerd
 - March 28, 2013, 07:01:12 am
Is there a way to know, other than checking for an immediate activate call, whether or not an instance of my device is actually being instantiated in the world or is the preview for placing instances in the world?
Posted by skylerd
 - March 27, 2013, 01:40:30 pm
As an alternative to a full scale asynchronous reworking of the device class (for now, until you have time), would it be fairly easy to add to your message pump handler a special user message that will do a callback to a void SomeFunc(void* param) function? That would also solve my problem.

P.S. In case I'm not being clear, I'm very very thankful for all your help here, and none of the above is a demand - just a suggestion for something quick & dirty if you wish to implement it.
Posted by Stephen
 - March 27, 2013, 01:25:46 pm
Quote from: skylerd on March 27, 2013, 08:00:15 am
How do your worker threads update their progress then? Is there any way to get a threadsafe falsify in a later PDK? Or perhaps add an update pass to the devices? If I had some way to get control of the main thread at a certain point I'd also be able to solve my problem.

Generally speaking, threading in WM is done at both a coarser and finer level than this -- devices do data-parallelism on their workload, and the WM core schedules task parallelism by having different devices work on different threads, but unfortunately this case falls right down the middle -- the device-class interface is single threaded. The main program thread "owns" the world, even if it does lend out a single device at a time to different threads for processing.

But I agree, it would be useful to have an asynchronous message queue exposed to devices so that they can affect the world. This is quite possible for post 2.3 release.
Posted by kalwalt
 - March 27, 2013, 12:48:50 pm
Really sorry for the off topic.! i forgot of the beta version... i will download it. If i have other problem i will open another topic. Thanks for the info, @skylerd.

p.s. also was noted by Remnant that new PDK is on beta site...  i read very quicly , sorry again ...
Posted by skylerd
 - March 27, 2013, 11:58:30 am
You need to grab the latest pdk from the beta site kalwalt. I've had no problems using it with visual studio 2010. beta site is at world-machine.com/beta. However, your post is completely off-topic - if you're still having problems, do you mind starting another thread? Thanks.
Posted by kalwalt
 - March 27, 2013, 11:14:51 am
Does it some news on MSVC 2010 support? I'm trying to build the inverted example but the upgrading process of the Visual Studio Solution fails. I would to develop some little plugins . It's better to wait or shall i install a previous VS version?

Posted by skylerd
 - March 27, 2013, 08:00:15 am
How do your worker threads update their progress then? Is there any way to get a threadsafe falsify in a later PDK? Or perhaps add an update pass to the devices? If I had some way to get control of the main thread at a certain point I'd also be able to solve my problem.
Posted by Stephen
 - March 26, 2013, 02:20:48 pm
So.. you can trigger a graph rebuild by calling Falsify() on a device, which will flag that device and all its successors for rebuilding.

However, there is still a problem, because this is not an asynchronous interface; if your communication thread called Falsify() whenever the external data changed, for example, it could easily do so at completely inappropriate times (during a build is bad but not catastrophic; but during serialization or right in the middle of a port connection could be very bad). In short the Falsify() or Preview() calls are not thread safe, and so should never be called from a secondary thread.

Off the top of my head, the best solution I can think of is to have a threadsafe collection in your manager that keeps track of all updates that have come in since the last synchronization.

Then override RunUI() in your device and before you call the default implementation, retrieve the set of changed devices and call Falsify() and/or Preview() on them appropriately. This call will be done on the main program thread and so is a safe operation.   ... so your changes won't sync till you open your user interface, but within that limitation it should work nicely. Alternatively, you could add an auxillary UI action by  overriding the set of:

   virtual int  getAuxActionSize() { return 1; };
   virtual bool RunAuxAction(int index) { domySynchAndPreview() };
   virtual char *getAuxActionName(int index); { return "Synchronize"; };

This would give you an explicit Synchronize action on the device that can be selected by right-clicking and then choosing Synch.

Posted by skylerd
 - March 26, 2013, 01:41:01 pm
As I've discussed previously, I'm doing some communication with an external application. From this application, I'm going to be setting a value within this node, that its outputting on an output node. I'm going to have a manager doing the communication with my external app, keeping a list of the devices it's tracking. It will have a separate thread reading set value messages from the external app. From there, I can set the value on the node fine, but I don't know how to let the world machine graph know a value has updated. How do I get WorldMachine to trigger a node's Activate function from a thread I've created?
Posted by Stephen
 - March 26, 2013, 11:00:13 am
Good questions. I will clarify the port function documentation (or rename the methods) for the final as many serve different purposes but sound similar.

If you have this arrangement:

Device A:
  Output 0 : port x

Device B:
  Input 0 : port y

FindPort should be what you want.

for example, calling A->FindPort(x) will set output params slot = 0, io = DEV_OUTPUT;

GetLinkedPort reaches through the wiring and compares to the ports on the other side of the a device's links -- basically "If I am connected to port target <someport> on a different device, what part of me is connected to it?".

Posted by skylerd
 - March 26, 2013, 09:08:16 am
So I've written an output port that will actually call notifyPortConnected on make/break of a link. However, I'm trying to get the slot index of the port, but calling GetLinkedPort on the owner always returns 0. Is there a function I can call on the device with a Port * to get the slot #? Is there a bug in GetLinkedPort right now?

[EDIT]: I found FindPort, and it works fine. What is GetLinkedPort supposed to return?