mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-06 18:26:22 +03:00
0031748: Application Framework - Efficient OCAF transactions in OCCT
This commit is contained in:
parent
d9d03f10c3
commit
dbab9c538c
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(TDF_Attribute,Standard_Transient)
|
IMPLEMENT_STANDARD_RTTIEXT(TDF_Attribute,Standard_Transient)
|
||||||
|
|
||||||
#undef TDF_DATA_COMMIT_OPTIMIZED
|
#define TDF_DATA_COMMIT_OPTIMIZED
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : TDF_Attribute
|
//function : TDF_Attribute
|
||||||
@ -131,6 +131,10 @@ void TDF_Attribute::Forget (const Standard_Integer aTransaction)
|
|||||||
mySavedTransaction = myTransaction;
|
mySavedTransaction = myTransaction;
|
||||||
myTransaction = aTransaction;
|
myTransaction = aTransaction;
|
||||||
myFlags = (myFlags | TDF_AttributeForgottenMsk);
|
myFlags = (myFlags | TDF_AttributeForgottenMsk);
|
||||||
|
#ifdef TDF_DATA_COMMIT_OPTIMIZED
|
||||||
|
if (myLabelNode)
|
||||||
|
myLabelNode->AttributesModified(Standard_True);
|
||||||
|
#endif
|
||||||
Validate(Standard_False);
|
Validate(Standard_False);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ typedef NCollection_Array1<Handle(TDF_AttributeDelta)> TDF_Array1OfAttributeIDel
|
|||||||
IMPLEMENT_STANDARD_RTTIEXT(TDF_Data,Standard_Transient)
|
IMPLEMENT_STANDARD_RTTIEXT(TDF_Data,Standard_Transient)
|
||||||
|
|
||||||
#undef DEB_DELTA_CREATION
|
#undef DEB_DELTA_CREATION
|
||||||
#undef TDF_DATA_COMMIT_OPTIMIZED
|
#define TDF_DATA_COMMIT_OPTIMIZED
|
||||||
|
|
||||||
#ifdef OCCT_DEBUG_DELTA
|
#ifdef OCCT_DEBUG_DELTA
|
||||||
#define TDF_Data_DebugModified(ACTION) \
|
#define TDF_Data_DebugModified(ACTION) \
|
||||||
|
57
tests/bugs/caf/bug31748_1
Normal file
57
tests/bugs/caf/bug31748_1
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
puts "==========="
|
||||||
|
puts "0031748: Application Framework - Efficient OCAF transactions in OCCT"
|
||||||
|
puts "==========="
|
||||||
|
|
||||||
|
NewDocument D
|
||||||
|
UndoLimit D 10
|
||||||
|
|
||||||
|
# number of labels of objects in the document
|
||||||
|
set labs 100000
|
||||||
|
# number of sub-labels of each object
|
||||||
|
set sublabs 10
|
||||||
|
|
||||||
|
NewCommand D
|
||||||
|
|
||||||
|
# store at each object-label sub-labels with two attributes at each
|
||||||
|
set creation_time [lindex [time {
|
||||||
|
for {set i 1} {$i <= $labs} {incr i} {
|
||||||
|
set lab [Label D 0:1:${i}]
|
||||||
|
SetName D ${lab} Object$i
|
||||||
|
for {set ii 1} {$ii <= $sublabs} {incr ii} {
|
||||||
|
set sublab [Label D ${lab}:$ii]
|
||||||
|
SetInteger D ${sublab} 10
|
||||||
|
SetReal D ${sublab} 12.3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}] 0]
|
||||||
|
|
||||||
|
set commit_time [lindex [time {
|
||||||
|
CommitCommand D
|
||||||
|
}] 0]
|
||||||
|
|
||||||
|
# modify only one object one attribute
|
||||||
|
NewCommand D
|
||||||
|
set one_modif_time [lindex [time {
|
||||||
|
SetInteger D 0:1:[expr $labs/2]:[expr $sublabs/2] 20
|
||||||
|
}] 0]
|
||||||
|
|
||||||
|
set one_commit_time [lindex [time {
|
||||||
|
CommitCommand D
|
||||||
|
}] 0]
|
||||||
|
|
||||||
|
puts "Tree creation time $creation_time mcs"
|
||||||
|
puts "Creation commit time $commit_time mcs"
|
||||||
|
puts "One attribute modification time $one_modif_time mcs"
|
||||||
|
puts "Commit of single modification time $one_commit_time mcs"
|
||||||
|
|
||||||
|
if {$creation_time > $commit_time} {
|
||||||
|
set max_creation $creation_time
|
||||||
|
} else {
|
||||||
|
set max_creation $commit_time
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check that creation time (or commit) is at least 1000 times slower than commit of one modification (normally 4000).
|
||||||
|
# Before the optimization it was only 150 times slower.
|
||||||
|
if { [expr $max_creation/1000.] < $one_commit_time } {
|
||||||
|
puts "Error : one modification time commit is too big relatively to the whole document creation or commit"
|
||||||
|
}
|
212
tests/bugs/caf/bug31748_2
Normal file
212
tests/bugs/caf/bug31748_2
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
puts "==========="
|
||||||
|
puts "0031748: Application Framework - Efficient OCAF transactions in OCCT"
|
||||||
|
puts "==========="
|
||||||
|
|
||||||
|
# This test checks different combinations of creation/modification/forget of attributes in
|
||||||
|
# transactions: when there are one or two attributes on a label, on father and child labels.
|
||||||
|
|
||||||
|
NewDocument D
|
||||||
|
UndoLimit D 100
|
||||||
|
|
||||||
|
# enumeration of actions: first come actions where no attribute needed on the label, after none, after - attribute must be on the label
|
||||||
|
set act_create 0
|
||||||
|
set act_createforget 1
|
||||||
|
set act_createmodify 2
|
||||||
|
set act_none 3
|
||||||
|
set act_modify 4
|
||||||
|
set act_modifyforget 5
|
||||||
|
set act_forget 6
|
||||||
|
set act_forgetcreate 7
|
||||||
|
# the number of possible actions that can be done on attribute
|
||||||
|
set actions 8
|
||||||
|
|
||||||
|
set act_afternone [expr $act_none+1]
|
||||||
|
|
||||||
|
# retuns 1 if after this action there exists attribute on the label
|
||||||
|
proc produces_attribute1 {action} {
|
||||||
|
global act_create act_modify act_forgetcreate act_createmodify
|
||||||
|
if {$action==$act_create || $action==$act_createmodify || $action==$act_modify || $action==$act_forgetcreate} {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# retuns 1 if after two actions there exists attribute on the label
|
||||||
|
proc produces_attribute2 {action1 action2} {
|
||||||
|
global act_create act_modify act_modifyforget act_forget act_createforget
|
||||||
|
if {[produces_attribute1 $action2]} {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if {$action2!=$act_forget && $action2!=$act_createforget && $action2!=$act_modifyforget && [produces_attribute1 $action1]} {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# retuns value of the attribute produced by two actions
|
||||||
|
proc produces_value {action1 action2} {
|
||||||
|
global act_modify act_createmodify act_none act_forgetcreate
|
||||||
|
if {$action2==$act_modify} {
|
||||||
|
if {$action1==$act_createmodify} {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if {$action2==$act_createmodify} {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if {$action1==$act_createmodify && $action2!=$act_forgetcreate} {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if {$action1==$act_none && $action1==$act_createmodify} {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
proc attribute_name attr_id {
|
||||||
|
if $attr_id==0 {
|
||||||
|
return Integer
|
||||||
|
}
|
||||||
|
return Real
|
||||||
|
}
|
||||||
|
|
||||||
|
proc do_action {label attr action} {
|
||||||
|
global D
|
||||||
|
set attrName [attribute_name $attr]
|
||||||
|
switch $action { # first there are atcions that leave attribute, then - none, then - that remove it
|
||||||
|
0 { # sets a new attribute
|
||||||
|
Set$attrName D $label 1
|
||||||
|
}
|
||||||
|
1 { # creates and immediately forgets a new attribute
|
||||||
|
Set$attrName D $label 1
|
||||||
|
if $attr==0 { # forget integer
|
||||||
|
ForgetAtt D $label 2a96b606-ec8b-11d0-bee7-080009dc3333
|
||||||
|
} else { # forget real
|
||||||
|
ForgetAtt D $label 2a96b60f-ec8b-11d0-bee7-080009dc3333
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 { # sets and modifies attribute
|
||||||
|
Set$attrName D $label 1
|
||||||
|
Set$attrName D $label 2
|
||||||
|
}
|
||||||
|
3 { # nothing to do
|
||||||
|
}
|
||||||
|
4 { # modifies (increments) an attribute value if it is already exists on this label
|
||||||
|
set value [Get$attrName D $label]
|
||||||
|
Set$attrName D $label [expr $value+1]
|
||||||
|
}
|
||||||
|
5 { # modifies and immediately forgets an attribute
|
||||||
|
set value [Get$attrName D $label]
|
||||||
|
Set$attrName D $label [expr $value+1]
|
||||||
|
if $attr==0 { # forget integer
|
||||||
|
ForgetAtt D $label 2a96b606-ec8b-11d0-bee7-080009dc3333
|
||||||
|
} else { # forget real
|
||||||
|
ForgetAtt D $label 2a96b60f-ec8b-11d0-bee7-080009dc3333
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6 { # forgets the attribute
|
||||||
|
if $attr==0 { # forget integer
|
||||||
|
ForgetAtt D $label 2a96b606-ec8b-11d0-bee7-080009dc3333
|
||||||
|
} else { # forget real
|
||||||
|
ForgetAtt D $label 2a96b60f-ec8b-11d0-bee7-080009dc3333
|
||||||
|
}
|
||||||
|
}
|
||||||
|
7 { # forgets and immediately creates an attribute
|
||||||
|
if $attr==0 { # forget integer
|
||||||
|
ForgetAtt D $label 2a96b606-ec8b-11d0-bee7-080009dc3333
|
||||||
|
} else { # forget real
|
||||||
|
ForgetAtt D $label 2a96b60f-ec8b-11d0-bee7-080009dc3333
|
||||||
|
}
|
||||||
|
Set$attrName D $label 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc check_attribute {action1 action2 lab attr} {
|
||||||
|
global D
|
||||||
|
set attrName [attribute_name $attr]
|
||||||
|
if [produces_attribute2 $action1 $action2] {
|
||||||
|
set value [Get$attrName D $lab]
|
||||||
|
set expected_value [produces_value $action1 $action2]
|
||||||
|
if $value!=$expected_value {
|
||||||
|
puts "Error : attribute $attrName value $value does not match the expected $expected_value at the label $lab"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set attributes [Attributes D $lab]
|
||||||
|
if {[lsearch $attributes TDataStd_$attrName]>=0} {
|
||||||
|
puts "Error : attribute $attrName exists but it should not at the label $lab"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
set lab_index 1
|
||||||
|
set num_variants 0
|
||||||
|
# cycles by variables t<transaction number>l<label number>a<attribute number> = action id
|
||||||
|
for {set t1l1a1 0} {$t1l1a1 < $act_afternone} {incr t1l1a1} {
|
||||||
|
for {set t1l2a1 0} {$t1l2a1 < $act_afternone} {incr t1l2a1} {
|
||||||
|
for {set t1l2a2 0} {$t1l2a2 < $act_afternone} {incr t1l2a2} {
|
||||||
|
set t2l1a1_min 0
|
||||||
|
set t2l1a1_max $actions
|
||||||
|
if [produces_attribute1 $t1l1a1] {set t2l1a1_min $act_none} {set t2l1a1_max $act_afternone}
|
||||||
|
for {set t2l1a1 $t2l1a1_min} {$t2l1a1 < $t2l1a1_max} {incr t2l1a1} {
|
||||||
|
set t2l2a1_min 0
|
||||||
|
set t2l2a1_max $actions
|
||||||
|
if [produces_attribute1 $t1l2a1] {set t2l2a1_min $act_none} {set t2l2a1_max $act_afternone}
|
||||||
|
for {set t2l2a1 $t2l2a1_min} {$t2l2a1 < $t2l2a1_max} {incr t2l2a1} {
|
||||||
|
set t2l2a2_min 0
|
||||||
|
set t2l2a2_max $actions
|
||||||
|
if [produces_attribute1 $t1l2a2] {set t2l2a2_min $act_none} {set t2l2a2_max $act_afternone}
|
||||||
|
for {set t2l2a2 $t2l2a2_min} {$t2l2a2 < $t2l2a2_max} {incr t2l2a2} {
|
||||||
|
set lab [Label D 0:$lab_index]
|
||||||
|
ForgetAll D $lab
|
||||||
|
set sublab [Label D $lab:1]
|
||||||
|
ForgetAll D $sublab
|
||||||
|
incr lab_index
|
||||||
|
incr num_variants
|
||||||
|
# avoid creation of too many labels (which is too slow)
|
||||||
|
if $lab_index==11 {
|
||||||
|
set lab_index 1
|
||||||
|
}
|
||||||
|
NewCommand D
|
||||||
|
do_action $lab 0 $t1l1a1
|
||||||
|
do_action $sublab 0 $t1l2a1
|
||||||
|
do_action $sublab 1 $t1l2a2
|
||||||
|
CommitCommand D
|
||||||
|
NewCommand D
|
||||||
|
do_action $lab 0 $t2l1a1
|
||||||
|
do_action $sublab 0 $t2l2a1
|
||||||
|
do_action $sublab 1 $t2l2a2
|
||||||
|
CommitCommand D
|
||||||
|
# check all attributes are correctly located in the tree
|
||||||
|
check_attribute $t1l1a1 $t2l1a1 $lab 0
|
||||||
|
check_attribute $t1l2a1 $t2l2a1 $sublab 0
|
||||||
|
check_attribute $t1l2a2 $t2l2a2 $sublab 1
|
||||||
|
# check attributes state after undo (but if all actions are None, there is no transaction, don't do it)
|
||||||
|
if {[expr $t2l1a1!=$act_none && $t2l1a1!=$act_createforget] || [expr $t2l2a1!=$act_none && $t2l2a1!=$act_createforget] || [expr $t2l2a2!=$act_none && $t2l2a2!=$act_createforget]} {
|
||||||
|
Undo D
|
||||||
|
}
|
||||||
|
check_attribute $act_none $t1l1a1 $lab 0
|
||||||
|
check_attribute $act_none $t1l2a1 $sublab 0
|
||||||
|
check_attribute $act_none $t1l2a2 $sublab 1
|
||||||
|
# check attributes state after redo
|
||||||
|
Undo D
|
||||||
|
Redo D
|
||||||
|
check_attribute $act_none $t1l1a1 $lab 0
|
||||||
|
check_attribute $act_none $t1l2a1 $sublab 0
|
||||||
|
check_attribute $act_none $t1l2a2 $sublab 1
|
||||||
|
# check attributes state after the second redo (but if all actions are None, there is no transaction, don't do it)
|
||||||
|
if {[expr $t2l1a1!=$act_none && $t2l1a1!=$act_createforget] || [expr $t2l2a1!=$act_none && $t2l2a1!=$act_createforget] || [expr $t2l2a2!=$act_none && $t2l2a2!=$act_createforget]} {
|
||||||
|
Redo D
|
||||||
|
}
|
||||||
|
check_attribute $t1l1a1 $t2l1a1 $lab 0
|
||||||
|
check_attribute $t1l2a1 $t2l2a1 $sublab 0
|
||||||
|
check_attribute $t1l2a2 $t2l2a2 $sublab 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts "Checked $num_variants variants"
|
268
tests/bugs/caf/bug31748_3
Normal file
268
tests/bugs/caf/bug31748_3
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
puts "==========="
|
||||||
|
puts "0031748: Application Framework - Efficient OCAF transactions in OCCT"
|
||||||
|
puts "==========="
|
||||||
|
|
||||||
|
# This test checks behavior of attributes in different combinations of transactions:
|
||||||
|
# creation/modification/deletion of attributes inside and outside of transaction and after
|
||||||
|
# that on Undo/Redo.
|
||||||
|
|
||||||
|
NewDocument D
|
||||||
|
UndoLimit D 100
|
||||||
|
|
||||||
|
# enumeration of actions: first come actions where no attribute needed on the label, after none, after - attribute must be on the label
|
||||||
|
set act_create 0
|
||||||
|
set act_createforget 1
|
||||||
|
set act_createmodify 2
|
||||||
|
set act_none 3
|
||||||
|
set act_modify 4
|
||||||
|
set act_modifyforget 5
|
||||||
|
set act_forget 6
|
||||||
|
set act_forgetcreate 7
|
||||||
|
# the number of possible actions that can be done on attribute
|
||||||
|
set actions 8
|
||||||
|
# some action undome in transaction
|
||||||
|
set act_undone 100
|
||||||
|
|
||||||
|
set act_afternone [expr $act_none+1]
|
||||||
|
|
||||||
|
# retuns 1 if after this action there exists attribute on the label
|
||||||
|
proc produces_attribute1 {action} {
|
||||||
|
global act_create act_modify act_forgetcreate act_createmodify
|
||||||
|
if {$action==$act_create || $action==$act_createmodify || $action==$act_modify || $action==$act_forgetcreate} {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# retuns 1 if after two actions there exists attribute on the label
|
||||||
|
proc produces_attribute2 {action1 action2} {
|
||||||
|
global act_create act_modify act_modifyforget act_forget act_createforget act_none act_forgetcreate act_undone
|
||||||
|
|
||||||
|
if {$action1 == $act_undone && $action2 == $act_modify} {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if {$action1 == $act_undone && $action2 == $act_forgetcreate} {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if {[produces_attribute1 $action2]} {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if {$action2!=$act_forget && $action2!=$act_createforget && $action2!=$act_modifyforget && [produces_attribute1 $action1]} {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# retuns value of the attribute produced by two actions
|
||||||
|
proc produces_value {action1 action2} {
|
||||||
|
global act_modify act_createmodify act_none act_forgetcreate
|
||||||
|
if {$action2==$act_modify} {
|
||||||
|
if {$action1==$act_createmodify} {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if {$action2==$act_createmodify} {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if {$action1==$act_createmodify && $action2!=$act_forgetcreate} {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if {$action1==$act_none && $action1==$act_createmodify} {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
proc attribute_name attr_id {
|
||||||
|
if $attr_id==0 {
|
||||||
|
return Integer
|
||||||
|
}
|
||||||
|
return Real
|
||||||
|
}
|
||||||
|
|
||||||
|
proc do_action {label attr action} {
|
||||||
|
global D
|
||||||
|
set attrName [attribute_name $attr]
|
||||||
|
switch $action { # first there are atcions that leave attribute, then - none, then - that remove it
|
||||||
|
0 { # sets a new attribute
|
||||||
|
Set$attrName D $label 1
|
||||||
|
}
|
||||||
|
1 { # creates and immediately forgets a new attribute
|
||||||
|
Set$attrName D $label 1
|
||||||
|
if $attr==0 { # forget integer
|
||||||
|
ForgetAtt D $label 2a96b606-ec8b-11d0-bee7-080009dc3333
|
||||||
|
} else { # forget real
|
||||||
|
ForgetAtt D $label 2a96b60f-ec8b-11d0-bee7-080009dc3333
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 { # sets and modifies attribute
|
||||||
|
Set$attrName D $label 1
|
||||||
|
Set$attrName D $label 2
|
||||||
|
}
|
||||||
|
3 { # nothing to do
|
||||||
|
}
|
||||||
|
4 { # modifies (increments) an attribute value if it is already exists on this label
|
||||||
|
set value [Get$attrName D $label]
|
||||||
|
Set$attrName D $label [expr $value+1]
|
||||||
|
}
|
||||||
|
5 { # modifies and immediately forgets an attribute
|
||||||
|
set value [Get$attrName D $label]
|
||||||
|
Set$attrName D $label [expr $value+1]
|
||||||
|
if $attr==0 { # forget integer
|
||||||
|
ForgetAtt D $label 2a96b606-ec8b-11d0-bee7-080009dc3333
|
||||||
|
} else { # forget real
|
||||||
|
ForgetAtt D $label 2a96b60f-ec8b-11d0-bee7-080009dc3333
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6 { # forgets the attribute
|
||||||
|
if $attr==0 { # forget integer
|
||||||
|
ForgetAtt D $label 2a96b606-ec8b-11d0-bee7-080009dc3333
|
||||||
|
} else { # forget real
|
||||||
|
ForgetAtt D $label 2a96b60f-ec8b-11d0-bee7-080009dc3333
|
||||||
|
}
|
||||||
|
}
|
||||||
|
7 { # forgets and immediately creates an attribute
|
||||||
|
if $attr==0 { # forget integer
|
||||||
|
ForgetAtt D $label 2a96b606-ec8b-11d0-bee7-080009dc3333
|
||||||
|
} else { # forget real
|
||||||
|
ForgetAtt D $label 2a96b60f-ec8b-11d0-bee7-080009dc3333
|
||||||
|
}
|
||||||
|
Set$attrName D $label 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc check_attribute {action1 action2 lab attr} {
|
||||||
|
global D
|
||||||
|
set attrName [attribute_name $attr]
|
||||||
|
if [produces_attribute2 $action1 $action2] {
|
||||||
|
set value [Get$attrName D $lab]
|
||||||
|
set expected_value [produces_value $action1 $action2]
|
||||||
|
if $value!=$expected_value {
|
||||||
|
puts "Error : attribute $attrName value $value does not match the expected $expected_value at the label $lab"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set attributes [Attributes D $lab]
|
||||||
|
if {[lsearch $attributes TDataStd_$attrName]>=0} {
|
||||||
|
puts "Error : attribute $attrName exists but it should not at the label $lab"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# special check for attributes if transaction->no transaction is performed and
|
||||||
|
# Undo->Redo done: modified attributes become modified, but removed attributes in the no-transaction
|
||||||
|
# do not removed after Redo
|
||||||
|
proc check_attribute_notransaction {action1 action_notr lab attr} {
|
||||||
|
global D
|
||||||
|
set attrName [attribute_name $attr]
|
||||||
|
if [produces_attribute2 $action1 $action_notr] {
|
||||||
|
set value [Get$attrName D $lab]
|
||||||
|
set expected_value [produces_value $action1 $action_notr]
|
||||||
|
if $value!=$expected_value {
|
||||||
|
puts "Error : attribute $attrName value $value does not match the expected $expected_value at the label $lab"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if [produces_attribute1 $action_notr]==0 {
|
||||||
|
set attributes [Attributes D $lab]
|
||||||
|
if {[lsearch $attributes TDataStd_$attrName]>=0} {
|
||||||
|
puts "Error : attribute $attrName exists but it should not at the label $lab"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
set lab_index 1
|
||||||
|
set num_variants 0
|
||||||
|
# cycles by variables t<operation number>a<attribute number> = action id
|
||||||
|
for {set t1a1 0} {$t1a1 < $act_afternone} {incr t1a1} {
|
||||||
|
for {set t1a2 0} {$t1a2 < $act_afternone} {incr t1a2} {
|
||||||
|
set t2a1_min 0
|
||||||
|
set t2a1_max $actions
|
||||||
|
if [produces_attribute1 $t1a1] {set t2a1_min $act_none} {set t2a1_max $act_afternone}
|
||||||
|
for {set t2a1 $t2a1_min} {$t2a1 < $t2a1_max} {incr t2a1} {
|
||||||
|
set t2a2_min 0
|
||||||
|
set t2a2_max $actions
|
||||||
|
if [produces_attribute1 $t1a2] {set t2a2_min $act_none} {set t2a2_max $act_afternone}
|
||||||
|
for {set t2a2 $t2a2_min} {$t2a2 < $t2a2_max} {incr t2a2} {
|
||||||
|
set lab [Label D 0:$lab_index]
|
||||||
|
ForgetAll D $lab
|
||||||
|
incr lab_index
|
||||||
|
incr num_variants
|
||||||
|
# for the first operation no transaction opened and closed
|
||||||
|
do_action $lab 0 $t1a1
|
||||||
|
do_action $lab 1 $t1a2
|
||||||
|
# after do operation in transaction
|
||||||
|
NewCommand D
|
||||||
|
do_action $lab 0 $t2a1
|
||||||
|
do_action $lab 1 $t2a2
|
||||||
|
CommitCommand D
|
||||||
|
# check all attributes are correctly located in the tree
|
||||||
|
check_attribute $t1a1 $t2a1 $lab 0
|
||||||
|
check_attribute $t1a2 $t2a2 $lab 1
|
||||||
|
# check attributes state after undo and then - redo (but if all actions are None, there is no transaction, don't do it)
|
||||||
|
if {[expr $t2a1!=$act_none && $t2a1!=$act_createforget] || [expr $t2a2!=$act_none && $t2a2!=$act_createforget]} {
|
||||||
|
Undo D
|
||||||
|
check_attribute $act_none $t1a1 $lab 0
|
||||||
|
check_attribute $act_none $t1a2 $lab 1
|
||||||
|
Redo D
|
||||||
|
check_attribute $t1a1 $t2a1 $lab 0
|
||||||
|
check_attribute $t1a2 $t2a2 $lab 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts "Checked $num_variants variants in cycles no transaction->transaction"
|
||||||
|
|
||||||
|
set num_variants 0
|
||||||
|
# cycles by variables t<operation number>a<attribute number> = action id
|
||||||
|
for {set t1a1 0} {$t1a1 < $act_afternone} {incr t1a1} {
|
||||||
|
for {set t1a2 0} {$t1a2 < $act_afternone} {incr t1a2} {
|
||||||
|
set t2a1_min 0
|
||||||
|
set t2a1_max $actions
|
||||||
|
if [produces_attribute1 $t1a1] {set t2a1_min $act_none} {set t2a1_max $act_afternone}
|
||||||
|
for {set t2a1 $t2a1_min} {$t2a1 < $t2a1_max} {incr t2a1} {
|
||||||
|
set t2a2_min 0
|
||||||
|
set t2a2_max $actions
|
||||||
|
if [produces_attribute1 $t1a2] {set t2a2_min $act_none} {set t2a2_max $act_afternone}
|
||||||
|
for {set t2a2 $t2a2_min} {$t2a2 < $t2a2_max} {incr t2a2} {
|
||||||
|
set lab [Label D 0:$lab_index]
|
||||||
|
incr lab_index
|
||||||
|
incr num_variants
|
||||||
|
# for the first operation open transaction
|
||||||
|
NewCommand D
|
||||||
|
do_action $lab 0 $t1a1
|
||||||
|
do_action $lab 1 $t1a2
|
||||||
|
CommitCommand D
|
||||||
|
# then no transaction is opened
|
||||||
|
do_action $lab 0 $t2a1
|
||||||
|
do_action $lab 1 $t2a2
|
||||||
|
# check all attributes are correctly located in the tree
|
||||||
|
check_attribute $t1a1 $t2a1 $lab 0
|
||||||
|
check_attribute $t1a2 $t2a2 $lab 1
|
||||||
|
# check attributes state after undo and then - redo (but if all actions are None, there is no transaction, don't do it)
|
||||||
|
if {[expr $t2a1!=$act_none && $t2a1!=$act_createforget] || [expr $t2a2!=$act_none && $t2a2!=$act_createforget]} {
|
||||||
|
Undo D
|
||||||
|
if {$t1a1 == $act_createforget || $t1a1 == $act_none} {
|
||||||
|
set first_tr $t1a1
|
||||||
|
} else {
|
||||||
|
set first_tr $act_undone
|
||||||
|
}
|
||||||
|
check_attribute $first_tr $t2a1 $lab 0
|
||||||
|
if {$t1a2 == $act_createforget || $t1a2 == $act_none} {
|
||||||
|
set first_tr $t1a2
|
||||||
|
} else {
|
||||||
|
set first_tr $act_undone
|
||||||
|
}
|
||||||
|
check_attribute $first_tr $t2a2 $lab 1
|
||||||
|
Redo D
|
||||||
|
check_attribute_notransaction $t1a1 $t2a1 $lab 0
|
||||||
|
check_attribute_notransaction $t1a2 $t2a2 $lab 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts "Checked $num_variants variants in cycles transaction->no transaction"
|
Loading…
x
Reference in New Issue
Block a user