Add property-based -filter to get_scenes / get_modes, and make Scene/Mode properties extensible (#456)

* support for filter in get_scene/mode

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* defineProperty overload

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* define and set user property

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* address review comments to generalize- current support for mode and scene

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* address second round comments- removed user from cmd names

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* remove defaults, check property vals against type defined

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* address reviews, indent

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* indent fix

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

---------

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
This commit is contained in:
Deepashree Sengupta 2026-07-10 12:37:48 -04:00 committed by GitHub
parent ceb7e6389d
commit a0de2706d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 483 additions and 111 deletions

View File

@ -30,6 +30,7 @@
#include "GraphClass.hh" #include "GraphClass.hh"
#include "NetworkClass.hh" #include "NetworkClass.hh"
#include "Scene.hh"
#include "SdcClass.hh" #include "SdcClass.hh"
#include "SearchClass.hh" #include "SearchClass.hh"
#include "StringUtil.hh" #include "StringUtil.hh"
@ -64,6 +65,16 @@ filterClocks(std::string_view filter_expression,
ClockSeq *clks, ClockSeq *clks,
Sta *sta); Sta *sta);
SceneSeq
filterScenes(std::string_view filter_expression,
SceneSeq *scenes,
Sta *sta);
ModeSeq
filterModes(std::string_view filter_expression,
ModeSeq *modes,
Sta *sta);
LibertyCellSeq LibertyCellSeq
filterLibCells(std::string_view filter_expression, filterLibCells(std::string_view filter_expression,
LibertyCellSeq *cells, LibertyCellSeq *cells,

View File

@ -28,6 +28,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <utility>
#include "LibertyClass.hh" #include "LibertyClass.hh"
#include "NetworkClass.hh" #include "NetworkClass.hh"
@ -61,109 +62,6 @@ private:
std::map<std::string, PropertyHandler, std::less<>> registry_; std::map<std::string, PropertyHandler, std::less<>> registry_;
}; };
class Properties
{
public:
Properties(Sta *sta);
PropertyValue getProperty(const Library *lib,
std::string_view property);
PropertyValue getProperty(const LibertyLibrary *lib,
std::string_view property);
PropertyValue getProperty(const Cell *cell,
std::string_view property);
PropertyValue getProperty(const LibertyCell *cell,
std::string_view property);
PropertyValue getProperty(const Port *port,
std::string_view property);
PropertyValue getProperty(const LibertyPort *port,
std::string_view property);
PropertyValue getProperty(const Instance *inst,
std::string_view property);
PropertyValue getProperty(const Pin *pin,
std::string_view property);
PropertyValue getProperty(const Net *net,
std::string_view property);
PropertyValue getProperty(Edge *edge,
std::string_view property);
PropertyValue getProperty(const Clock *clk,
std::string_view property);
PropertyValue getProperty(const Scene *scene,
std::string_view property);
PropertyValue getProperty(const Mode *mode,
std::string_view property);
PropertyValue getProperty(PathEnd *end,
std::string_view property);
PropertyValue getProperty(Path *path,
std::string_view property);
PropertyValue getProperty(TimingArcSet *arc_set,
std::string_view property);
// Define handler for external property.
// properties->defineProperty("foo",
// [] (const Instance *, Sta *) -> PropertyValue {
// return PropertyValue("bar");
// });
void defineProperty(std::string_view property,
const PropertyRegistry<const Library *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Cell *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const LibertyCell *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Port *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const LibertyPort *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Instance *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Pin *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Net *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Clock *>::PropertyHandler &handler);
protected:
PropertyValue portSlew(const Port *port,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue portSlack(const Port *port,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue pinArrival(const Pin *pin,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue pinSlack(const Pin *pin,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue pinSlew(const Pin *pin,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue delayPropertyValue(Delay delay);
PropertyValue resistancePropertyValue(float res);
PropertyValue capacitancePropertyValue(float cap);
PropertyValue edgeDelay(Edge *edge,
const RiseFall *rf,
const MinMax *min_max);
PropertyRegistry<const Library*> registry_library_;
PropertyRegistry<const LibertyLibrary*> registry_liberty_library_;
PropertyRegistry<const Cell*> registry_cell_;
PropertyRegistry<const LibertyCell*> registry_liberty_cell_;
PropertyRegistry<const Port*> registry_port_;
PropertyRegistry<const LibertyPort*> registry_liberty_port_;
PropertyRegistry<const Instance*> registry_instance_;
PropertyRegistry<const Pin*> registry_pin_;
PropertyRegistry<const Net*> registry_net_;
PropertyRegistry<const Clock*> registry_clock_;
Sta *sta_;
};
// Adding a new property type // Adding a new property type
// value union (string values use std::string* so the union stays trivial) // value union (string values use std::string* so the union stays trivial)
// enum Type // enum Type
@ -262,4 +160,151 @@ private:
const Unit *unit_; const Unit *unit_;
}; };
// Key for user-defined property values: the object instance and the
// property name.
class PropertyKey
{
public:
PropertyKey(const void *object,
std::string_view property);
bool operator<(const PropertyKey &key) const;
private:
const void *object_;
std::string property_;
};
class Properties
{
public:
Properties(Sta *sta);
PropertyValue getProperty(const Library *lib,
std::string_view property);
PropertyValue getProperty(const LibertyLibrary *lib,
std::string_view property);
PropertyValue getProperty(const Cell *cell,
std::string_view property);
PropertyValue getProperty(const LibertyCell *cell,
std::string_view property);
PropertyValue getProperty(const Port *port,
std::string_view property);
PropertyValue getProperty(const LibertyPort *port,
std::string_view property);
PropertyValue getProperty(const Instance *inst,
std::string_view property);
PropertyValue getProperty(const Pin *pin,
std::string_view property);
PropertyValue getProperty(const Net *net,
std::string_view property);
PropertyValue getProperty(Edge *edge,
std::string_view property);
PropertyValue getProperty(const Clock *clk,
std::string_view property);
PropertyValue getProperty(const Scene *scene,
std::string_view property);
PropertyValue getProperty(const Mode *mode,
std::string_view property);
PropertyValue getProperty(PathEnd *end,
std::string_view property);
PropertyValue getProperty(Path *path,
std::string_view property);
PropertyValue getProperty(TimingArcSet *arc_set,
std::string_view property);
// Define handler for external property.
// properties->defineProperty("foo",
// [] (const Instance *, Sta *) -> PropertyValue {
// return PropertyValue("bar");
// });
void defineProperty(std::string_view property,
const PropertyRegistry<const Library *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Cell *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const LibertyCell *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Port *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const LibertyPort *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Instance *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Pin *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Net *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Clock *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Scene *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
const PropertyRegistry<const Mode *>::PropertyHandler &handler);
// User-defined, per-object mutable properties. defineProperty registers
// a property of the given value type ("bool", "float" or "string");
// setProperty sets the value on one object. Objects the property was never
// set on read back as an empty (none) value. The property is read through
// the same registry path as every other property so get_property /
// get_* -filter work unchanged.
template<class TYPE>
void defineProperty(std::string_view object_type,
std::string_view property,
std::string_view value_type);
void setProperty(const void *object,
std::string_view object_type,
std::string_view property,
std::string_view value);
protected:
PropertyValue portSlew(const Port *port,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue portSlack(const Port *port,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue pinArrival(const Pin *pin,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue pinSlack(const Pin *pin,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue pinSlew(const Pin *pin,
const RiseFallBoth *rf,
const MinMax *min_max);
PropertyValue delayPropertyValue(Delay delay);
PropertyValue resistancePropertyValue(float res);
PropertyValue capacitancePropertyValue(float cap);
PropertyValue edgeDelay(Edge *edge,
const RiseFall *rf,
const MinMax *min_max);
PropertyValue::Type propertyType(std::string_view type);
PropertyValue coercePropertyValue(PropertyValue::Type type,
std::string_view value);
PropertyRegistry<const Library*> registry_library_;
PropertyRegistry<const LibertyLibrary*> registry_liberty_library_;
PropertyRegistry<const Cell*> registry_cell_;
PropertyRegistry<const LibertyCell*> registry_liberty_cell_;
PropertyRegistry<const Port*> registry_port_;
PropertyRegistry<const LibertyPort*> registry_liberty_port_;
PropertyRegistry<const Instance*> registry_instance_;
PropertyRegistry<const Pin*> registry_pin_;
PropertyRegistry<const Net*> registry_net_;
PropertyRegistry<const Clock*> registry_clock_;
PropertyRegistry<const Scene*> registry_scene_;
PropertyRegistry<const Mode*> registry_mode_;
// Value types of user-defined properties keyed by object type name and
// property name.
std::map<std::pair<std::string, std::string>, PropertyValue::Type> prop_types_;
// User-defined property values.
std::map<PropertyKey, PropertyValue> prop_values_;
Sta *sta_;
};
} // namespace sta } // namespace sta

View File

@ -42,6 +42,7 @@
#include "GraphCmp.hh" #include "GraphCmp.hh"
#include "Liberty.hh" #include "Liberty.hh"
#include "LibertyClass.hh" #include "LibertyClass.hh"
#include "Mode.hh"
#include "Network.hh" #include "Network.hh"
#include "NetworkClass.hh" #include "NetworkClass.hh"
#include "PathEnd.hh" #include "PathEnd.hh"
@ -497,6 +498,30 @@ filterClocks(std::string_view filter_expression,
}, sta); }, sta);
} }
SceneSeq
filterScenes(std::string_view filter_expression,
SceneSeq *scenes,
Sta *sta)
{
return filterObjects<Scene>(filter_expression, scenes,
[] (const Scene *scene1,
const Scene *scene2) {
return scene1->name() < scene2->name();
}, sta);
}
ModeSeq
filterModes(std::string_view filter_expression,
ModeSeq *modes,
Sta *sta)
{
return filterObjects<Mode>(filter_expression, modes,
[] (const Mode *mode1,
const Mode *mode2) {
return mode1->name() < mode2->name();
}, sta);
}
LibertyCellSeq LibertyCellSeq
filterLibCells(std::string_view filter_expression, filterLibCells(std::string_view filter_expression,
LibertyCellSeq *cells, LibertyCellSeq *cells,

View File

@ -1531,6 +1531,22 @@ filter_clocks(const char *filter_expression,
return filterClocks(filter_expression, clocks, sta); return filterClocks(filter_expression, clocks, sta);
} }
SceneSeq
filter_scenes(const char *filter_expression,
SceneSeq *scenes)
{
sta::Sta *sta = Sta::sta();
return filterScenes(filter_expression, scenes, sta);
}
ModeSeq
filter_modes(const char *filter_expression,
ModeSeq *modes)
{
sta::Sta *sta = Sta::sta();
return filterModes(filter_expression, modes, sta);
}
LibertyCellSeq LibertyCellSeq
filter_lib_cells(const char *filter_expression, filter_lib_cells(const char *filter_expression,
LibertyCellSeq *cells) LibertyCellSeq *cells)

View File

@ -26,6 +26,7 @@
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#include <tuple>
#include <utility> #include <utility>
#include "Clock.hh" #include "Clock.hh"
@ -1205,7 +1206,9 @@ Properties::getProperty(const Scene *scene,
|| property == "full_name") || property == "full_name")
return PropertyValue(scene->name()); return PropertyValue(scene->name());
else else
throw PropertyUnknown("scene", property); // Unknown properties throw PropertyUnknown; a user-defined property
// never set on this scene returns a none value.
return registry_scene_.getProperty(scene, property, "scene", sta_);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -1218,7 +1221,9 @@ Properties::getProperty(const Mode *mode,
|| property == "full_name") || property == "full_name")
return PropertyValue(mode->name()); return PropertyValue(mode->name());
else else
throw PropertyUnknown("mode", property); // Unknown properties throw PropertyUnknown; a user-defined property
// never set on this mode returns a none value.
return registry_mode_.getProperty(mode, property, "mode", sta_);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -1360,6 +1365,119 @@ Properties::defineProperty(std::string_view property,
registry_clock_.defineProperty(property, handler); registry_clock_.defineProperty(property, handler);
} }
void
Properties::defineProperty(std::string_view property,
const PropertyRegistry<const Scene *>::PropertyHandler &handler)
{
registry_scene_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
const PropertyRegistry<const Mode *>::PropertyHandler &handler)
{
registry_mode_.defineProperty(property, handler);
}
////////////////////////////////////////////////////////////////
// Value type from the define_property -type argument.
PropertyValue::Type
Properties::propertyType(std::string_view type)
{
if (type == "bool" || type == "boolean")
return PropertyValue::Type::bool_;
else if (type == "float" || type == "double" || type == "number")
return PropertyValue::Type::float_;
else if (type == "string")
return PropertyValue::Type::string;
else
sta_->report()->error(2210, "unknown property type '{}' (use bool, float or string).",
type);
return PropertyValue::Type::none;
}
PropertyValue
Properties::coercePropertyValue(PropertyValue::Type type,
std::string_view value)
{
switch (type) {
case PropertyValue::Type::bool_:
if (stringEqual(value, "true") || value == "1")
return PropertyValue(true);
if (stringEqual(value, "false") || value == "0")
return PropertyValue(false);
sta_->report()->error(2212, "'{}' is not a bool property value.", value);
return PropertyValue();
case PropertyValue::Type::float_: {
auto [number, valid] = stringFloat(std::string(value));
if (!valid)
sta_->report()->error(2215, "'{}' is not a float property value.", value);
return PropertyValue(number, sta_->units()->scalarUnit());
}
default:
return PropertyValue(std::string(value));
}
}
PropertyKey::PropertyKey(const void *object,
std::string_view property) :
object_(object),
property_(property)
{
}
bool
PropertyKey::operator<(const PropertyKey &key) const
{
return std::tie(object_, property_)
< std::tie(key.object_, key.property_);
}
template<class TYPE>
void
Properties::defineProperty(std::string_view object_type,
std::string_view property,
std::string_view value_type)
{
prop_types_[{std::string(object_type), std::string(property)}] =
propertyType(value_type);
std::string name(property);
typename PropertyRegistry<const TYPE *>::PropertyHandler handler =
[this, name] (const TYPE *object,
Sta *) -> PropertyValue {
auto value_iter = prop_values_.find(PropertyKey(object, name));
if (value_iter != prop_values_.end())
return value_iter->second;
// Never set on this object.
return PropertyValue();
};
defineProperty(property, handler);
}
// Object types the tcl interface exposes user properties on.
template void Properties::defineProperty<Scene>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<Mode>(std::string_view,
std::string_view,
std::string_view);
void
Properties::setProperty(const void *object,
std::string_view object_type,
std::string_view property,
std::string_view value)
{
auto type_iter = prop_types_.find({std::string(object_type),
std::string(property)});
if (type_iter == prop_types_.end())
sta_->report()->error(2211, "{} property '{}' is not defined.",
object_type, property);
prop_values_[PropertyKey(object, property)] =
coercePropertyValue(type_iter->second, value);
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
template<class TYPE> template<class TYPE>

View File

@ -25,6 +25,7 @@
%{ %{
#include "Property.hh" #include "Property.hh"
#include "Report.hh"
#include "Sta.hh" #include "Sta.hh"
using namespace sta; using namespace sta;
@ -137,6 +138,39 @@ mode_property(Mode *mode,
return properties.getProperty(mode, property); return properties.getProperty(mode, property);
} }
void
define_property_cmd(const char *object_type,
const char *property,
const char *type)
{
Properties &properties = Sta::sta()->properties();
std::string_view object_type_view(object_type);
if (object_type_view == "scene")
properties.defineProperty<Scene>(object_type, property, type);
else if (object_type_view == "mode")
properties.defineProperty<Mode>(object_type, property, type);
else
Sta::sta()->report()->error(2209, "define_property -object_type {} not supported.",
object_type);
}
void
set_property_cmd(void *object,
const char *object_type,
const char *property,
const char *value)
{
Properties &properties = Sta::sta()->properties();
std::string_view object_type_view(object_type);
if (object_type_view == "Scene")
properties.setProperty(object, "scene", property, value);
else if (object_type_view == "Mode")
properties.setProperty(object, "mode", property, value);
else
Sta::sta()->report()->error(2214, "set_property unsupported object type {}.",
object_type);
}
PropertyValue PropertyValue
path_end_property(PathEnd *end, path_end_property(PathEnd *end,
const char *property) const char *property)

View File

@ -120,5 +120,33 @@ proc get_property_object_type { object_type object_name quiet } {
return [lindex $object 0] return [lindex $object 0]
} }
define_cmd_args "define_property" \
{-object_type scene|mode -type bool|float|string property}
proc define_property { args } {
parse_key_args "define_property" args keys {-object_type -type} flags {}
check_argc_eq1 "define_property" $args
if { ![info exists keys(-object_type)] } {
sta_error 2207 "define_property -object_type must be specified."
}
if { ![info exists keys(-type)] } {
sta_error 2208 "define_property -type must be specified."
}
define_property_cmd $keys(-object_type) [lindex $args 0] $keys(-type)
}
define_cmd_args "set_property" {object property value}
proc set_property { args } {
check_argc_eq3 "set_property" $args
set object [lindex $args 0]
set prop [lindex $args 1]
set value [lindex $args 2]
if { ![is_object $object] } {
sta_error 2213 "set_property $object is not an object."
}
set_property_cmd $object [object_type $object] $prop $value
}
# sta namespace end. # sta namespace end.
} }

View File

@ -112,10 +112,10 @@ proc set_scene { args } {
################################################################ ################################################################
define_cmd_args "get_scenes" {[-modes mode_names] scene_names} define_cmd_args "get_scenes" {[-modes mode_names] [-filter expr] scene_names}
proc get_scenes { args } { proc get_scenes { args } {
parse_key_args "get_scenes" args keys {-modes} flags {} parse_key_args "get_scenes" args keys {-modes -filter} flags {}
check_argc_eq0or1 "get_scenes" $args check_argc_eq0or1 "get_scenes" $args
if { [llength $args] == 0 } { if { [llength $args] == 0 } {
@ -132,18 +132,34 @@ proc get_scenes { args } {
} }
lappend modes $mode lappend modes $mode
} }
return [find_mode_scenes_matching $scene_name $modes] set scenes [find_mode_scenes_matching $scene_name $modes]
} else { } else {
return [find_scenes_matching $scene_name] set scenes [find_scenes_matching $scene_name]
} }
if { [info exists keys(-filter)] } {
set scenes [filter_scenes $keys(-filter) $scenes]
}
return $scenes
} }
################################################################ ################################################################
define_cmd_args "get_modes" {mode_name} define_cmd_args "get_modes" {[-filter expr] [mode_name]}
proc get_modes { args } { proc get_modes { args } {
return [find_modes [lindex $args 0]] parse_key_args "get_modes" args keys {-filter} flags {}
check_argc_eq0or1 "get_modes" $args
if { [llength $args] == 0 } {
set mode_name "*"
} else {
set mode_name [lindex $args 0]
}
set modes [find_modes $mode_name]
if { [info exists keys(-filter)] } {
set modes [filter_modes $keys(-filter) $modes]
}
return $modes
} }
################################################################ ################################################################

View File

@ -1218,6 +1218,10 @@ using namespace sta;
$1 = tclListSeq<Mode*>($input, SWIGTYPE_p_Mode, interp); $1 = tclListSeq<Mode*>($input, SWIGTYPE_p_Mode, interp);
} }
%typemap(in) ModeSeq* {
$1 = tclListSeqPtr<Mode*>($input, SWIGTYPE_p_Mode, interp);
}
%typemap(out) ModeSeq { %typemap(out) ModeSeq {
seqTclList<ModeSeq, Mode>($1, SWIGTYPE_p_Mode, interp); seqTclList<ModeSeq, Mode>($1, SWIGTYPE_p_Mode, interp);
} }
@ -1251,6 +1255,10 @@ using namespace sta;
$1 = tclListSeq<Scene*>($input, SWIGTYPE_p_Scene, interp); $1 = tclListSeq<Scene*>($input, SWIGTYPE_p_Scene, interp);
} }
%typemap(in) SceneSeq* {
$1 = tclListSeqPtr<Scene*>($input, SWIGTYPE_p_Scene, interp);
}
%typemap(out) SceneSeq { %typemap(out) SceneSeq {
seqTclList<SceneSeq, Scene>($1, SWIGTYPE_p_Scene, interp); seqTclList<SceneSeq, Scene>($1, SWIGTYPE_p_Scene, interp);
} }

View File

@ -4,3 +4,30 @@ scene2
[get_modes *] [get_modes *]
mode1 mode1
mode2 mode2
[get_scenes -filter {name == scene1}]
scene1
[get_scenes -filter {name =~ scene*}]
scene1
scene2
[get_scenes -filter {name != scene1}]
scene2
[get_modes -filter {name == mode2}]
mode2
[get_modes -filter {name =~ mode*}]
mode1
mode2
[get_property scene1 active]
1
[get_property scene2 active] (unset)
<>
[get_scenes -filter {active == true}]
scene1
[get_scenes -filter {active == false}] (scene2 unset)
[get_scenes -filter {active}]
scene1
[get_scenes -filter {!active}]
scene2
[get_property scene2 active] (set false)
0
[get_scenes -filter {active == false}] (scene2 set false)
scene2

View File

@ -18,3 +18,47 @@ report_object_names [get_scenes *]
puts {[get_modes *]} puts {[get_modes *]}
report_object_names [get_modes *] report_object_names [get_modes *]
puts {[get_scenes -filter {name == scene1}]}
report_object_names [get_scenes -filter {name == scene1}]
puts {[get_scenes -filter {name =~ scene*}]}
report_object_names [get_scenes -filter {name =~ scene*}]
puts {[get_scenes -filter {name != scene1}]}
report_object_names [get_scenes -filter {name != scene1}]
puts {[get_modes -filter {name == mode2}]}
report_object_names [get_modes -filter {name == mode2}]
puts {[get_modes -filter {name =~ mode*}]}
report_object_names [get_modes -filter {name =~ mode*}]
# User-defined bool property. scene1 set active, scene2 left unset.
define_property -object_type scene -type bool active
set_property [get_scenes scene1] active true
puts {[get_property scene1 active]}
puts [get_property [get_scenes scene1] active]
puts {[get_property scene2 active] (unset)}
puts "<[get_property [get_scenes scene2] active]>"
puts {[get_scenes -filter {active == true}]}
report_object_names [get_scenes -filter {active == true}]
# Unset does not match false; only an explicitly set value does.
puts {[get_scenes -filter {active == false}] (scene2 unset)}
report_object_names [get_scenes -filter {active == false}]
puts {[get_scenes -filter {active}]}
report_object_names [get_scenes -filter {active}]
puts {[get_scenes -filter {!active}]}
report_object_names [get_scenes -filter {!active}]
set_property [get_scenes scene2] active false
puts {[get_property scene2 active] (set false)}
puts [get_property [get_scenes scene2] active]
puts {[get_scenes -filter {active == false}] (scene2 set false)}
report_object_names [get_scenes -filter {active == false}]