How do signals work?

Hello :)

Could anyone explain how a signal works? I have made an attachment and I want its material to change if Genesis does. I have worked out how to apply "duplicate" the Gen material when the attachment first loads, but now I am stuck on updating it whenever Gens material changes. I just don't understand how to setup a signal. I know my code is a bit rough at the moment but will fix it up if I can figure this last step out. I have done hours of google searches and found only 2 posts that remotely help, but all the links from them are dead. I have got the SDK docs but they don't explain how to use things, just what is available.

 

I am assuming I am meant to use "settingsChanged(DzMaterial*)" but I just don't know what to do with it.

My Code atm:

// DAZ Studio version 4.9.0.63 filetype DAZ Scriptvar aNodes = Scene.getSelectedNodeList();if (aNodes.Length > 1){	return false;}var sScript = 'c2.dsa';	var oSrcNode = aNodes[0];var oTgtNode = oSrcNode.findNodeChild ("g3Lump");var oSrcObject = oSrcNode.getObject();var oTgtObject = oTgtNode.getObject();var oSrcShape = oSrcObject.getCurrentShape();var oTgtShape = oTgtObject.getCurrentShape();var oSrcMaterial = oSrcShape.findMaterial( "Torso" );var oTgtMaterial = oTgtShape.findMaterial( "Torso" );var oContext = new DzElementDuplicateContext(); 	// Duplicate the material	var oDupeMaterial = oSrcMaterial.doDuplicateElement( oContext ); 	// Set the name of the duplicate to the name of the target	oDupeMaterial.name = oTgtMaterial.name; 	// Set the label of the duplicate to the label of the target	oDupeMaterial.setLabel( oTgtMaterial.getLabel() ); 	// If the duplicate material classname and the source material classname do not match	if( oDupeMaterial.className() != oSrcMaterial.className() ){		// If the duplicate material inherits types we know provide a setMaterialName function		if( oDupeMaterial.inherits( "DzShaderMaterial" ) || oDupeMaterial.inherits( "DzBrickMaterial" ) ){			// Copy the material name			oDupeMaterial.setMaterialName( oSrcMaterial.getMaterialName() );		}	} 	// Re-create any aliases that exist	oContext.createAlaises(); 	// Re-create any ERC links that exist	oContext.createERC(); 	// Resolve references to the source material	oContext.doResolve(); 	// Finalize the duplication	oContext.doFinalize(); 	oTgtShape.replaceMaterial( oTgtMaterial, oDupeMaterial );var cbm = App.getCallBackMgr();var cb = cbm.createCallBack("chMat", sScript, true);cb.setConnection(oSrcMaterial, 'settingsChanged(DzMaterial*)');

 

Thanks to anyone who can help me :) an example of any kind would be appreciated or just an explanation would also be awesome!

Comments

  • DrumeDrume Posts: 21

    If anyone can point me to any examples or tutorials that would be really great :)

  • DrumeDrume Posts: 21

    I have altered

    var cbm = App.getCallBackMgr();var cb = cbm.createCallBack("chMat", sScript, true);cb.setConnection(oSrcMaterial, 'settingsChanged(DzMaterial*)');

    to

     connect(oSrcShape, "materialListChanged()", hasChanged());
    function hasChanged(){ 	MessageBox.information( "MyScript finished successfully.", "MyScript", "&OK" ); 	}

    When I test it in the scriptIDE it triggers the connection and runs haschanged(), this also occurs when I first add the attachment onto Genesis. But for both these events the materials on oSrcShape (gen) are not actually changing but it is being triggered, and when I change the material on gen it does not trigger. I think I am missing something bloody obvious!

    Any help would be appreciated :)

  • simtenerosimtenero Posts: 383
    edited March 2016

    Hey Drume, it's been a while since you posted this, but hopefully this is still useful to you.

     

    First off, remove the "()" from the connect line, change:

    connect(oSrcShape, "materialListChanged()", hasChanged());

    to

    connect(oSrcShape, "materialListChanged()", hasChanged);

    That should keep it from triggering when you first run the script (I have no idea why, just does :-P).

    Next, you need to have the script wait and listen for events.  You need a "while loop" that keeps running the "processEvents()" function until some condition is met.  A quick example:

    const changeComplete = false;while (!changeComplete){   processEvents();}

    Then just make sure your hasChanged function satisfies the condition when it's done doing its thing, otherwise your script will just keep on running:

    function hasChanged(){ 	MessageBox.information( "MyScript finished successfully.", "MyScript", "&OK" );    changeComplete = true;}

     

    That's not all tested, but hopefully it helps!

    Post edited by simtenero on
  • simtenero said:

    Hey Drume, it's been a while since you posted this, but hopefully this is still useful to you.

     

    First off, remove the "()" from the connect line, change:

    connect(oSrcShape, "materialListChanged()", hasChanged());

    to

    connect(oSrcShape, "materialListChanged()", hasChanged);

    That should keep it from triggering when you first run the script (I have no idea why, just does :-P).

    I would think that having hasChanged() exeutes the fucntion and then uses its return value as the parameter, while hasChanged passes (a pointer to) the actual function object, which is what you want.

  • simtenerosimtenero Posts: 383

     

    I would think that having hasChanged() exeutes the fucntion and then uses its return value as the parameter, while hasChanged passes (a pointer to) the actual function object, which is what you want.

    That makes sense!

  • DrumeDrume Posts: 21

    Thanks for your help! have been lost in study but will have a look at all this :) also been learning c++ which will come in handy!

Sign In or Register to comment.