[Closed] Are dynamic structs possible? Reopen
It’s not the same, but… how about this?
Struct STRUCTURE_COLLECTION_MANAGER
(
private
globalStructs,
globalStNames,
ID,
public
_,
fn setStruct structID =
(
if isKindOf structID integer do
(
ID = structID
_ = globalStructs[ID]
return globalStNames[ID]
)
if isKindOf structID StructDef do
(
_ = structID
ID = findItem globalStructs structID
return globalStNames[ID]
)
if isKindOf structID name or isKindOf structID string do
(
structID = structID as name
ID = findItem globalStNames structID
_ = globalStructs[ID]
return globalStNames[ID]
)
),
fn current = globalStNames[ID],
on create do
(
-- You can fill here the arrays with your method reading from an INI file
globalStructs = #(MY_ARRAY_STRUCTURE, MY_MATH_STRUCTURE)
globalStNames = #(#arrayOps, #mathOps)
-- Default value:
ID = 1
_ = globalStructs[ID]
)
)
GLOBAL SCM = STRUCTURE_COLLECTION_MANAGER()
/*
-- Use:
SCM._.reverseArray #(1,2,3)
SCM.current()
SCM.setStruct #mathOps
scm._.isInteger 4
scm.setStruct 1
a=#(1,2,3); scm._.removeItem a 3; a
scm.setStruct MY_MATH_STRUCTURE
scm._.roundToInt 25.45 10
*/
EDIT: Happy New Year!!
Nice one andres!, Happy year too
You script is another angle of view
I think we are more close now…
I’m sorry for starting this topic from end, wee need to start at beginning
one example of dynamic structure (in Flash called Class)
I will show it in actionscript language for better understanding
- [package classes] this header shown directory location of this class
@example: D:\work\my_project\classes*.* - [public class Person] this like in maxscript –> Struct person ()
package classes
{
public class Person
{
// Properties.
public var _age:Number;
public var _name:String;
// Constructor.
public function Person(age:Number, name:String)
{
_age = age;
_name = name;
}
}
}
@usage
import classes.Person;
var marty:Person = new Person(24, "Marty");
trace (marty._age) // 24
- now we gonna to extend class Person and make new Class –> Person_Mage
package classes // we can stay in same directory
{
public class Person_Mage extends Person
{
// add some new property
public var _inteligence:Number;
// Constructor.
public function Person_Mage (age:Number, name:String, inteligence:Number)
{
_age = age;
_name = name;
_inteligence = inteligence;
}
// Create person mage function
public function throwFireball(target:Point):Bollean
{
if inteligence > 50 then trace("You hit target!") else trace("You miss....")
return inteligence > 50
}
}
}
@usage
import classes.Person_Mage ;
var marty:Person_Mage = new Person_Mage (24, "Marty", 80);
trace (marty.throwFireball(pos_x, pos_y, pos_z)) // "You hit target!"
I dot know if this is the best example but extending mechanic is visible
here is one maxscript example
- Base Dotnet Form Struct
Global mcBaseForm
if ::mcBaseForm != undefined do try(mcBaseForm.Close())catch()
(
struct NET_FN (
fn netRect pos size = (dotnetObject "Drawing.Rectangle" pos.x pos.y size.x size.y),
fn netColor clr = ((dotNetClass "Drawing.Color").fromArgb clr.r clr.g clr.b)
)
local mcs, dia, net = NET_FN()
local mcs, dia
struct DOTNET_FORM_BASE (
-- Default Properties
form = dotNetObject "MaxCustomControls.Maxform",
lblT = dotNetObject "label",
tlp = dotNetObject "TableLayoutPanel",
form_size,
form_color,
debug = 0,
-- Default Functions
fn maxHW = (
local hv = DotNetObject "NativeWindow"
hv.AssignHandle (DotNetObject "System.IntPtr" (Windows.GetMaxHWND()))
return hv
),
fn close = (dia.close()),
fn changeBackcolor s a = (s.backColor = net.netColor mcs.form_color),
-- SetUp Interface
fn init pos:[400, 350] size:[350, 250] backcolor:yellow title:"Max Form" = (
form_size = size
form_color = backcolor
form.text = title
form.StartPosition = form.StartPosition.Manual
form.bounds = net.netRect pos size
-- Default Events
dotnet.AddEventHandler form "BackColorChanged" changeBackcolor --override backcolorchanged event (without this form color is default)
local hv = maxHW ()
form.show(hv) -- Shows the form with the specified owner (MAX) to the user (creatd by lo)
hv.ReleaseHandle()
OK
),
initIt = init pos:[400, 350] size:[350, 250] title:"My Form 1 v0.01"
)
mcBaseForm = DOTNET_FORM_BASE()
mcs = mcBaseForm --structure shortcut (simplest use)
dia = mcBaseForm.form --form instance
)
- and here is “extended version” (is rewritten from begin)
should be an extension because is have all like in base (but how to do this?)
Global mcCompactForm
if ::mcCompactForm != undefined do try(mcCompactForm.Close())catch()
(
struct NET_FN (
fn netRect pos size = (dotnetObject "Drawing.Rectangle" pos.x pos.y size.x size.y),
fn netColor clr = ((dotNetClass "Drawing.Color").fromArgb clr.r clr.g clr.b),
fn mcFormSnap form pos = (
local newpos = mouse.screenpos - pos
local net_pos = dotnetObject "Drawing.Point" newpos.x newpos.y
form.location = net_pos
)
)
local mcs, dia, net = NET_FN()
struct DOTNET_FORM_BASE (
-- Default Properties
form = dotNetObject "MaxCustomControls.Maxform",
lblT = dotNetObject "label",
tlp = dotNetObject "TableLayoutPanel",
netDmPos, --mouse pos on dialog
form_size,
form_color,
bar_height = 14,
border_offset = 2,
debug = 0,
-- Default Functions
fn maxHW = (
local hv = DotNetObject "NativeWindow"
hv.AssignHandle (DotNetObject "System.IntPtr" (Windows.GetMaxHWND()))
return hv
),
fn close = (dia.close()),
fn changeBackcolor s a = (s.backColor = net.netColor mcs.form_color),
--Move / Snap Dialog
fn onLblTMouseMove s a = ( if a.Button == a.Button.left do net.mcFormSnap dia mcs.netDmPos), --drag form
fn onLblTMouseDown s a = ( --start drag
dia.cursor.current = netCursors.Hand
if a.Button == a.Button.left do ( --enable drag
mcs.netDmPos = [dia.MousePosition.x, dia.MousePosition.y] - [dia.left, dia.top]
)
),
fn onLblTMouseUp s a = (if a.Button == a.Button.right then mcs.close()), --stop drag or close
-- Custom Functions
-- SetUp Interface
fn init pos:[400, 350] size:[350, 250] backcolor:yellow forecolor:white toolbarcolor:blue title:"Max Form" = (
form_size = size
form_color = backcolor
form.text = title
form.ControlBox = false --hide main bar
form.ShowInTaskbar = false
form.StartPosition = form.StartPosition.Manual
form.bounds = net.netRect pos size
form.FormBorderStyle = form.FormBorderStyle.none
form.BackColor = net.netColor backcolor
form.opacity = 1
--toolbar
lblT.bounds = net.netRect [border_offset, border_offset] [form_size.x - border_offset*10 , bar_height]
lblT.BackColor = net.netColor toolbarcolor
lblT.ForeColor = net.netColor forecolor
lblT.Text = title
--Componnts Layout
tlp.Bounds = net.netRect [border_offset, bar_height + border_offset * 2] [form_size.x - 20, form_size.y - 36]
tlp.backColor = net.netColor backcolor
-- Default Events
dotNet.addEventHandler lblT "MouseMove" onLblTMouseMove
dotNet.addEventHandler lblT "MouseDown" onLblTMouseDown
dotNet.addEventHandler lblT "MouseUp" onLblTMouseUp
dotnet.AddEventHandler form "BackColorChanged" changeBackcolor --override backcolorchanged event (without this form color is default)
--Add Controls
form.controls.addRange ( #(tlp, lblT) )
local hv = maxHW ()
form.show(hv) -- Shows the form with the specified owner (MAX) to the user (creatd by lo)
hv.ReleaseHandle()
OK
),
initIt = init pos: [800, 350] size:[350, 250] title:"My Form 2 v0.01"
)
mcCompactForm = DOTNET_FORM_BASE()
mcs = mcCompactForm --structure shortcut (simplest use)
dia = mcCompactForm.form --form instance
)
second structure should be extension from the first one
That seems more a matter of inheritance than of dynamic class.
Really hard to imagine how to do it.
Without any usability, but fun … (just to start the new year )
[code]
struct parentStruct
(
-- Public Struct Data and Functions
parentVar_01,
parentVar_02 = 5,
parentVar_03 = "Hello",
fn parentFN_01 = parentVar_01 * parentVar_02,
fn parentFN_02 data = data * 3 * this._parentVar_01,
-- FOR INHERITANCE
-------------------------------------------------
-- Inherit Functions (Fixed, always the same for parent and children)
fn _getHeader = this.stHeader,
fn _getPublic = this.stPublic,
fn _getPrivate = this.stPrivate,
fn _getClose = this.stClose,
-------------------------------------------------
-------------------------------------------------
-- Fixed Inherit Function ONLY for first parent
fn _createDerivedClass child=
(
txtPublic = this.stPublic + child._getPublic()
txtPrivate = this.stPrivate + child._getPrivate()
txtClose = this.stClose + "\n" + child._getClose()
txt = "struct " + child._getHeader() + "("
txt += txtPublic
txt += this.stInheritFN
txt += "private " + txtPrivate
txt += "stHeader = \"" + child._getHeader() + "\","
txtPublic = substituteString txtPublic "\\" "\\\\"
txtPublic = substituteString txtPublic "\"" "\\\""
txt += "stPublic = \"" + txtPublic + "\","
txtPrivate = substituteString txtPrivate "\\" "\\\\"
txtPrivate = substituteString txtPrivate "\"" "\\\""
txt += "stPrivate = \"" + txtPrivate + "\","
fixtxtClose = substituteString txtClose "\\" "\\\\"
fixtxtClose = substituteString fixtxtClose "\"" "\\\""
txt += "stClose = \"" + fixtxtClose + "\","
fixstInheritFN = substituteString this.stInheritFN "\\" "\\\\"
fixstInheritFN = substituteString fixstInheritFN "\"" "\\\""
txt += "stInheritFN = \"" + fixstInheritFN + "\","
txt += "on create do (" + txtClose + "))"
derivedClass = execute txt
),
--------------------------------------------------------
private
-- Private Struct Data and Functions
_parentVar_01 = 10,
-- FOR INHERITANCE
------------------------------------------
-- Data needed for inheritance
-- Must fill for each parent and child (it's a copy of struct definition)
stHeader = "parentStruct",
stPublic =
"
parentVar_01,
parentVar_02 = 5,
parentVar_03 = \"Hello\",
fn parentFN_01 = parentVar_01 * parentVar_02,
fn parentFN_02 data = data * 3 * this._parentVar_01,
",
stPrivate =
"
_parentVar_01 = 10,
",
stClose = "",
--------------------------------------
-- Fixed data and functions ONLY for first parent
stInheritFN =
"
fn _getHeader = this.stHeader,
fn _getPublic = this.stPublic,
fn _getPrivate = this.stPrivate,
fn _getClose = this.stClose,
fn _createDerivedClass child=
(
txtPublic = this.stPublic + child._getPublic()
txtPrivate = this.stPrivate + child._getPrivate()
txtClose = this.stClose + \"\\n\" + child._getClose()
txt = \"struct \" + child._getHeader() + \"(\"
txt += txtPublic
txt += this.stInheritFN
txt += \"private \" + txtPrivate
txt += \"stHeader = \\\"\" + child._getHeader() + \"\\\",\"
txtPublic = substituteString txtPublic \"\\\\\" \"\\\\\\\\\"
txtPublic = substituteString txtPublic \"\\\"\" \"\\\\\\\"\"
txt += \"stPublic = \\\"\" + txtPublic + \"\\\",\"
txtPrivate = substituteString txtPrivate \"\\\\\" \"\\\\\\\\\"
txtPrivate = substituteString txtPrivate \"\\\"\" \"\\\\\\\"\"
txt += \"stPrivate = \\\"\" + txtPrivate + \"\\\",\"
fixtxtClose = substituteString txtClose \"\\\\\" \"\\\\\\\\\"
fixtxtClose = substituteString fixtxtClose \"\\\"\" \"\\\\\\\"\"
txt += \"stClose = \\\"\" + fixtxtClose + \"\\\",\"
fixstInheritFN = substituteString this.stInheritFN \"\\\\\" \"\\\\\\\\\"
fixstInheritFN = substituteString fixstInheritFN \"\\\"\" \"\\\\\\\"\"
txt += \"stInheritFN = \\\"\" + fixstInheritFN + \"\\\",\"
txt += \"on create do (\" + txtClose + \"))\"
derivedClass = execute txt
),
",
-------------------------------
on create do ()
)
parentStruct = parentStruct()
struct ChildStruct
(
childVar_01,
childVar_02 = 7,
fn childFN_01 = childVar_01 * childVar_02,
-- FOR INHERITANCE
-------------------------------------------------
-- Inherit Functions (Fixed, always the same for parent and children)
fn _getHeader = this.stHeader,
fn _getPublic = this.stPublic,
fn _getPrivate = this.stPrivate,
fn _getClose = this.stClose,
-------------------------------------------------
private
-- FOR INHERITANCE
------------------------------------------
-- Data needed for inheritance
-- Must fill for each parent and child (it's a copy of struct definition)
stHeader = "ChildStruct",
stPublic =
"
childVar_01,
childVar_02 = 7,
fn childFN_01 = childVar_01 * childVar_02,
",
stPrivate = "",
stClose =
"
print childVar_02
print \"Creating\"
",
------------------------------------------
on create do
(
print childVar_02
print "Creating"
)
)
ChildStruct = ChildStruct()
completeChildStruct = parentStruct._createDerivedClass ChildStruct
completeChildStruct = completeChildStruct()
struct subChildStruct
(
subchildVar_01 = 55,
-- FOR INHERITANCE
-------------------------------------------------
-- Inherit Functions (Fixed, always the same for parent and children)
fn _getHeader = this.stHeader,
fn _getPublic = this.stPublic,
fn _getPrivate = this.stPrivate,
fn _getClose = this.stClose,
-------------------------------------------------
private
_subchildVar_01 = 66,
-- FOR INHERITANCE
------------------------------------------
-- Data needed for inheritance
-- Must fill for each parent and child (it's a copy of struct definition)
stHeader = "subChildStruct",
stPublic =
"
subchildVar_01 = 55,
",
stPrivate =
"
_subchildVar_01 = 66,
",
stClose =
"
",
------------------------------------------
on create do
(
)
)
subChildStruct = subChildStruct()
RecompleteChildStruct = completeChildStruct._createDerivedClass subChildStruct
RecompleteChildStruct = RecompleteChildStruct()
[code]
hi Andres,
your script looks promising.
it will take some time for me to explore it.