[Closed] Just a replica
several years ago i showed first time the principle – One tool, one script, one structure
now i see many tools are written this way
its a system where you define tool, it’s interface, callbacks, and macros all in one structure
Hehe… I hv tried many times.
I’m still at THAT level.
Hopefully one day.
I have a feeling that on this site it has become completely impossible to find any kind of archive.
Ok. I try to find this topic, and once again show how I design and organize my tools.
If I remember correctly you use single structure and everything else is “inside” this structure – rollout, functions, etc.
I have this code of yours, saved on my PC.
global GeneralSceneOps
(
struct GeneralSceneStruct
(
fn destroy = try(closeRolloutFloater GeneralSceneOps.dialog) catch(),
title = "General Scene Helpers",
dialogWidth = 250,
dialogHeight = 400,
dialog,
MatStruct =
(
struct MatStruct (material, slot)
),
ObjectRollout = rollout ObjectRollout "Objects"
(
local owner = if owner != undefined do owner
button deleteall_bt "Delete All Objects" align:#left width:(owner.dialogWidth - 30) offset:[-5,0]
on deleteall_bt pressed do undo "Delete All" on
(
format ">>> %\n" owner
delete objects
)
),
materials = #(),
MaterialRollout = rollout MaterialRollout "Materials"
(
local owner = if owner != undefined do owner
button collectmats_bt "Collect Editor Materials" align:#left width:(owner.dialogWidth - 30) offset:[-5,0]
on collectmats_bt pressed do
(
owner.materials = for k=1 to 24 collect (owner.MatStruct (medit.GetTopMtlSlot k) k)
format "mats: %\n" owner.materials
)
),
rollouts = #(ObjectRollout, MaterialRollout),
fn show =
(
destroy()
dialog = newRolloutFloater title dialogWidth dialogHeight
for r in rollouts do addRollout r dialog
),
on create do
(
destroy()
rollouts.owner = this
)
)
GeneralSceneOps = GeneralSceneStruct()
ok
)
GeneralSceneOps.show()
I categorized all of my scripts like this, But now I have a question. Do you think is it efficient to call a function from structure like this?
MyCompany.MyTools.MySkinTools.GetBones()
Yes. It’s absolutely safe and clear for code reading.
But we all know that ‘accessing’ a struct and struct members take a time and mxs memory allocation. So if you need to call some method frequently or repeatedly it’s better to store a pointer to the method first and you use later in a loop for example.
struct MyStruct
(
fn call_method a b = (a*b)
)
(
gc()
d = MyStruct()
t0 = timestamp()
h0 = heapfree
for k=1 to 100000 do
(
d.call_method 100 100
)
format "time:% heap:%\n" (timestamp() - t0) (h0 - heapfree)
)
(
gc()
d = MyStruct()
t0 = timestamp()
h0 = heapfree
call_method = d.call_method
for k=1 to 100000 do
(
call_method 100 100
)
format "time:% heap:%\n" (timestamp() - t0) (h0 - heapfree)
)
so, looking on the method name (GetBones) it’s ok to call it like MyCompany.MyTools.MySkinTools.GetBones()
because it’s a ‘once-used’ method (it doesn’t really effect performance and memory use)
but a function for example GetLocalVertexNormal which is expected to be used in a loop should be call as:
getLocalVertexNormal = MyCompany.MyTools.PolyMethods.GetLocalVertexNormal
<in loop> getLocalVertexNormal ...