Notifications
Clear all

[Closed] structs and referencing functions within itself

hi

Say i have a struct which has a bunch of functions in it and within one of the functions i want to call another funtion that is also withing the struct, it should be something like

struct myStruct
(
	fn a =
	(
		do something
	),

	fn b =
	(
		myStruct.a()
	)	
)

right?

Is this bad practice or even technically possible because im getting some really unpredictable results

Cheers
Dave

Edit: or thinking about it would i need to declare all the functions at the top of the struct?

14 Replies

Is this bad practice or even technically possible because im getting some really unpredictable results

It is a fine and common practice.

The unpredictable results are probably because of the way you are calling function a.

I’m rusty in maxscript syntax, but I don’t think you want to have the myStruct. prefix. This has to do with the definition vs. the instance of the structure.

1 Reply
(@gazybara)
Joined: 10 months ago

Posts: 0

I will use “this” instead of “myStruct”

You can use the keyword “this” to reference internal struct variables and functions.


 struct foo
 (
 	a = "hi",
 	b = "there",
 	fn fooPrint = (format "% %
" this.a this.b),
 	fn doit = (this.fooPrint())
 )
 z = foo()
 z.doit()

like everyone says , use “this” to refer to any variable or function defined inside the struct.
the reason is because the name of the instantiated struct can be almost anything.

if we did this:

struct myStruct
(
	fn a =( do something),
	fn b =(myStruct.a())	
)

myStruct= myStruct() --create an instance named 'myStruct'
myOtherStruct= myStruct()--create an instance named 'myOtherStruct'

myStruct.b() --calls  myStruct.a() as you'd expect
myOtherStruct.b() --calls   myStruct.a()  as well (NOT myOtherStruct.a())


on the other hand:

struct myStruct
(
	fn a =( do something),
	fn b =(this.a())	
)

myStruct= myStruct() --create an instance named 'myStruct'
myOtherStruct= myStruct()--create an instance named 'myOtherStruct'

myStruct.b() --calls myStruct.a() as you'd expect
myOtherStruct.b() --calls myOtherStruct.a() as you'd expect


Wow I did not know that max had the concept of “this”
To fill in a little more I found a couple of reasons why I was getting unpredictable results, firstly the unpredictable results were from a dotNet UI in a dll that became unresponsive, this was because if I reloaded the maxscripts to update changes in the struct the UI would suddenly loose all connections to and inside the struct, probably because the instance got re instanciated and internally something got re arrange. This also happened when I open a new max scene, which puzzles me more.

Any who thanks to everyone
I shall now go and read more on this (I know bad pun sorry couldn’t resist, back under my rock now, this will be very usefull… Sorry)

Dave

ok, i appreciate the help but im going to ask for a little more

The “this” keyword has helped with a couple of issues i was getting so thanks again for that :D. The next issue i cant figure out is, running the function via the listener, everything runs fine BUT, when i run the same function through the clicking a button in the dontNet UI it complains stating

>> MAXScript dotNet event handler Exception:
– Runtime error: Struct member access requires instance: this <<

which makes no sense to me as the event is pointing at a completely different function, not the one that it is erroring on

Any thoughts on this would be greatly appreciated

Thanks
Dave

1 Reply
(@alexanderh)
Joined: 10 months ago

Posts: 0

How have you nested your code?

If you have the following:
>Struct
>>rollout
>>>button
>>>on button press do this.function

The button would look for function within the rollout. This is because the rollout is the “owner” of the button. You need to look a level higher to get at those functions.

To do this, I learned from Dennis that you have to assign ownership and then reference owner instead of this.

for example:


struct testing
(
fn Testfunction = 
(
return "Hello"
),

fn createRollout =
(
rollout rollMain "Rollout"
(
	local owner = if owner != undefined do owner

	button btn_Test "Button"
	on btn_Test pressed do owner.Testfunction()
)
rollMain.owner = this --This tells the rollout that we can call owner to reach the struct contents.
rollMain
)
)

The button is in a form in a dll so im doing

dotnet.loadAssembly ddlPath
dn_UI = dotNetObject "blahDeBlah.BlahDe"
dn_UI .show()
dotNet.addEventHandler dn_UI .btn_Scan "click" functionName 

so there isnt a rollout that owns the button unfortunately, otherwise im sure that would work

Cheers

Where is your functionName?
I am missing scope to try and help further.

I get the error about “this” that you do, when my function call is incorrectly scoped.
I assume that where you add the EventHandler, you are not in the correct scope to call this.function.

there is a trick with using the dotnet object tag property to pass a structure to event handler function:


 struct TestStruct 
 (
 	test = "test",
 	fn onClick s e = 
 	(
 		format ">>>>>>> %
" s.tag.value.test
 	),
 	bt = 
 	(
 		bt = dotnetobject "Button"
 		bt.Dock = bt.Dock.Top
 		bt.Tag = dotnetmxsvalue this
 		dotnet.addeventhandler bt "MouseClick" onClick
 		bt
 	)
 )
 str = TestStruct()
 
 form = dotnetobject "Form"
 form.controls.add str.bt
 
 form.show()
 

you can find more samples on this forum…

struct scnHlth
(
	dn_scnHlthUI = undefined ,
	shDllPath = "C:\Program Files (x86)\Autodesk\3ds Max 2013\scripts\Core\SceneHealth.dll",

	fn getSceneHealth = 
	(
		this.getGeoHealth() -- FAILS HERE
	),	
	
	fn getGeoHealth objs:undefined =
	(
		-- do stuff with the geo
	),
	
	fn Show_SH_UI =
	(
		try ( dn_scnHlthUI.close() ) catch ()
	
		try
		(
			dotnet.loadAssembly this.shDllPath
			this.dn_scnHlthUI = dotNetObject "LT_SceneHealth.SceneHealthUI"
			this.dn_scnHlthUI.show()
			dotNet.addEventHandler dn_scnHlthUI.btn_Scan "click" getSceneHealth
			return true
		)
		catch
		(
			messagebox "Failed to load Scene Health Dll" title:"Fail-splosion"
			return false
		)
	)
)

with the code above i get the requires instance thing but with “this” added into the event handle (which i now believe is required) i get nothing at all from pressing the button

dotNet.addEventHandler dn_scnHlthUI.btn_Scan "click" this.getSceneHealth

does nothing when the button is pressed

Thanks again

Page 1 / 2