pub trait State<ET: EngineTypes>: Sized + Clone {
Show 69 methods
// Required methods
fn new(nullfont: ET::Font, aux: &mut EngineAux<ET>) -> Self;
fn aftergroup(&mut self, token: ET::Token);
fn register_primitive(
&mut self,
aux: &mut EngineAux<ET>,
name: &'static str,
cmd: PrimitiveCommand<ET>,
);
fn primitives(&self) -> &PrimitiveCommands<ET>;
fn push(
&mut self,
aux: &mut EngineAux<ET>,
group_type: GroupType,
line_number: usize,
);
fn pop(&mut self, aux: &mut EngineAux<ET>, mouth: &mut ET::Mouth);
fn get_group_type(&self) -> Option<GroupType>;
fn get_group_level(&self) -> usize;
fn get_current_font(&self) -> &ET::Font;
fn set_current_font(
&mut self,
aux: &mut EngineAux<ET>,
fnt: ET::Font,
globally: bool,
);
fn get_textfont(&self, fam: u8) -> &ET::Font;
fn set_textfont(
&mut self,
aux: &mut EngineAux<ET>,
fam: u8,
fnt: ET::Font,
globally: bool,
);
fn get_scriptfont(&self, fam: u8) -> &ET::Font;
fn set_scriptfont(
&mut self,
aux: &mut EngineAux<ET>,
fam: u8,
fnt: ET::Font,
globally: bool,
);
fn get_scriptscriptfont(&self, fam: u8) -> &ET::Font;
fn set_scriptscriptfont(
&mut self,
aux: &mut EngineAux<ET>,
fam: u8,
fnt: ET::Font,
globally: bool,
);
fn get_par_token(&self) -> ET::CSName;
fn set_par_token(&mut self, par: ET::CSName);
fn get_catcode_scheme(&self) -> &CategoryCodeScheme<ET::Char>;
fn set_catcode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
cc: CategoryCode,
globally: bool,
);
fn get_sfcode(&self, c: ET::Char) -> u16;
fn set_sfcode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
sfcode: u16,
globally: bool,
);
fn get_lccode(&self, c: ET::Char) -> ET::Char;
fn set_lccode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
lccode: ET::Char,
globally: bool,
);
fn get_uccode(&self, c: ET::Char) -> ET::Char;
fn set_uccode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
uccode: ET::Char,
globally: bool,
);
fn get_delcode(&self, c: ET::Char) -> ET::Int;
fn set_delcode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
delcode: ET::Int,
globally: bool,
);
fn get_mathcode(&self, c: ET::Char) -> u32;
fn set_mathcode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
mathcode: u32,
globally: bool,
);
fn get_endline_char(&self) -> Option<ET::Char>;
fn set_endline_char(
&mut self,
aux: &EngineAux<ET>,
c: Option<ET::Char>,
globally: bool,
);
fn get_escape_char(&self) -> Option<ET::Char>;
fn set_escape_char(
&mut self,
aux: &EngineAux<ET>,
c: Option<ET::Char>,
globally: bool,
);
fn get_newline_char(&self) -> Option<ET::Char>;
fn set_newline_char(
&mut self,
aux: &EngineAux<ET>,
c: Option<ET::Char>,
globally: bool,
);
fn get_parshape(&self) -> &Vec<(ET::Dim, ET::Dim)>;
fn take_parshape(&mut self) -> Vec<(ET::Dim, ET::Dim)>;
fn set_parshape(
&mut self,
aux: &EngineAux<ET>,
parshape: Vec<(ET::Dim, ET::Dim)>,
globally: bool,
);
fn get_int_register(&self, idx: usize) -> ET::Int;
fn set_int_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: ET::Int,
globally: bool,
);
fn get_primitive_int(&self, name: PrimitiveIdentifier) -> ET::Int;
fn set_primitive_int(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: ET::Int,
globally: bool,
);
fn get_dim_register(&self, idx: usize) -> ET::Dim;
fn set_dim_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: ET::Dim,
globally: bool,
);
fn get_skip_register(&self, idx: usize) -> Skip<ET::Dim>;
fn set_skip_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: Skip<ET::Dim>,
globally: bool,
);
fn get_muskip_register(&self, idx: usize) -> MuSkip<ET::MuDim>;
fn set_muskip_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: MuSkip<ET::MuDim>,
globally: bool,
);
fn get_toks_register(&self, idx: usize) -> &TokenList<ET::Token>;
fn set_toks_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: TokenList<ET::Token>,
globally: bool,
);
fn get_box_register(&self, idx: usize) -> Option<&TeXBox<ET>>;
fn get_box_register_mut(&mut self, idx: usize) -> Option<&mut TeXBox<ET>>;
fn take_box_register(&mut self, idx: usize) -> Option<TeXBox<ET>>;
fn set_box_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: Option<TeXBox<ET>>,
globally: bool,
);
fn get_primitive_dim(&self, name: PrimitiveIdentifier) -> ET::Dim;
fn set_primitive_dim(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: ET::Dim,
globally: bool,
);
fn get_primitive_skip(&self, name: PrimitiveIdentifier) -> Skip<ET::Dim>;
fn set_primitive_skip(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: Skip<ET::Dim>,
globally: bool,
);
fn get_primitive_muskip(
&self,
name: PrimitiveIdentifier,
) -> MuSkip<ET::MuDim>;
fn set_primitive_muskip(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: MuSkip<ET::MuDim>,
globally: bool,
);
fn get_primitive_tokens(
&self,
name: PrimitiveIdentifier,
) -> &TokenList<ET::Token>;
fn set_primitive_tokens(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: TokenList<ET::Token>,
globally: bool,
);
fn get_command(&self, name: &ET::CSName) -> Option<&TeXCommand<ET>>;
fn set_command(
&mut self,
aux: &EngineAux<ET>,
name: ET::CSName,
cmd: Option<TeXCommand<ET>>,
globally: bool,
);
fn get_ac_command(&self, c: ET::Char) -> Option<&TeXCommand<ET>>;
fn set_ac_command(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
cmd: Option<TeXCommand<ET>>,
globally: bool,
);
// Provided methods
fn register_index(i: ET::Int) -> Option<usize> { ... }
fn get_mathfonts(&self, fam: u8) -> (ET::Font, ET::Font, ET::Font) { ... }
}Expand description
A TeX state; holds all the different parameters, equivalents, registers etc.
The canoncial implementation is TeXState.
Note that we do not require ET:EngineTypes<State=Self> - this allows for
implementing your own State by just wrapping an existing implementation in a new wrapper struct and pass on functionality
to the inner State, which would otherwise
fail since ET::State would be the outer wrapper struct, not the inner one.
Required Methods§
Sourcefn aftergroup(&mut self, token: ET::Token)
fn aftergroup(&mut self, token: ET::Token)
Append a Token to be inserted when the current group ends (i.e. \aftergroup)
Sourcefn register_primitive(
&mut self,
aux: &mut EngineAux<ET>,
name: &'static str,
cmd: PrimitiveCommand<ET>,
)
fn register_primitive( &mut self, aux: &mut EngineAux<ET>, name: &'static str, cmd: PrimitiveCommand<ET>, )
register a new PrimitiveCommand. Should only be called during engine initialization.
Sourcefn primitives(&self) -> &PrimitiveCommands<ET>
fn primitives(&self) -> &PrimitiveCommands<ET>
return the set of all registered PrimitiveCommands.
Sourcefn push(
&mut self,
aux: &mut EngineAux<ET>,
group_type: GroupType,
line_number: usize,
)
fn push( &mut self, aux: &mut EngineAux<ET>, group_type: GroupType, line_number: usize, )
push a new group level to the scoping stack; line_number is used for \tracinggroups
Sourcefn pop(&mut self, aux: &mut EngineAux<ET>, mouth: &mut ET::Mouth)
fn pop(&mut self, aux: &mut EngineAux<ET>, mouth: &mut ET::Mouth)
pop a group level from the scoping stack. Needs the mouth to insert the \aftergroup Tokens (if set)
Sourcefn get_group_type(&self) -> Option<GroupType>
fn get_group_type(&self) -> Option<GroupType>
The current [GroupType] (i.e. \currentgrouptype`).
Sourcefn get_group_level(&self) -> usize
fn get_group_level(&self) -> usize
The current group level/depth (0 being the top level; i.e. \currentgrouplevel)
Sourcefn get_current_font(&self) -> &ET::Font
fn get_current_font(&self) -> &ET::Font
Get the current Font
Sourcefn set_current_font(
&mut self,
aux: &mut EngineAux<ET>,
fnt: ET::Font,
globally: bool,
)
fn set_current_font( &mut self, aux: &mut EngineAux<ET>, fnt: ET::Font, globally: bool, )
Set the current Font
Sourcefn get_textfont(&self, fam: u8) -> &ET::Font
fn get_textfont(&self, fam: u8) -> &ET::Font
Get the current \textfont for the given family number, where fam is 0..15
Sourcefn set_textfont(
&mut self,
aux: &mut EngineAux<ET>,
fam: u8,
fnt: ET::Font,
globally: bool,
)
fn set_textfont( &mut self, aux: &mut EngineAux<ET>, fam: u8, fnt: ET::Font, globally: bool, )
Set the current \textfont for the given family number, where fam is 0..15
Sourcefn get_scriptfont(&self, fam: u8) -> &ET::Font
fn get_scriptfont(&self, fam: u8) -> &ET::Font
Get the current \scriptfont for the given family number, where fam is 0..15
Sourcefn set_scriptfont(
&mut self,
aux: &mut EngineAux<ET>,
fam: u8,
fnt: ET::Font,
globally: bool,
)
fn set_scriptfont( &mut self, aux: &mut EngineAux<ET>, fam: u8, fnt: ET::Font, globally: bool, )
Set the current \scriptfont for the given family number, where fam is 0..15
Sourcefn get_scriptscriptfont(&self, fam: u8) -> &ET::Font
fn get_scriptscriptfont(&self, fam: u8) -> &ET::Font
Get the current \scriptscriptfont for the given family number, where fam is 0..15
Sourcefn set_scriptscriptfont(
&mut self,
aux: &mut EngineAux<ET>,
fam: u8,
fnt: ET::Font,
globally: bool,
)
fn set_scriptscriptfont( &mut self, aux: &mut EngineAux<ET>, fam: u8, fnt: ET::Font, globally: bool, )
Set the current \scriptscriptfont for the given family number, where fam is 0..15
Sourcefn get_par_token(&self) -> ET::CSName
fn get_par_token(&self) -> ET::CSName
Get the current \par token
Sourcefn set_par_token(&mut self, par: ET::CSName)
fn set_par_token(&mut self, par: ET::CSName)
Set the current \par token
Sourcefn get_catcode_scheme(&self) -> &CategoryCodeScheme<ET::Char>
fn get_catcode_scheme(&self) -> &CategoryCodeScheme<ET::Char>
Get the current CategoryCodeScheme
Sourcefn set_catcode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
cc: CategoryCode,
globally: bool,
)
fn set_catcode( &mut self, aux: &EngineAux<ET>, c: ET::Char, cc: CategoryCode, globally: bool, )
Set the current CategoryCode for a character
Sourcefn get_sfcode(&self, c: ET::Char) -> u16
fn get_sfcode(&self, c: ET::Char) -> u16
Get the current space factor code \sfcode for a character
Sourcefn set_sfcode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
sfcode: u16,
globally: bool,
)
fn set_sfcode( &mut self, aux: &EngineAux<ET>, c: ET::Char, sfcode: u16, globally: bool, )
Set the current space factor code \sfcode for a character
Sourcefn get_lccode(&self, c: ET::Char) -> ET::Char
fn get_lccode(&self, c: ET::Char) -> ET::Char
Get the current lower case code \lccode for a character
Sourcefn set_lccode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
lccode: ET::Char,
globally: bool,
)
fn set_lccode( &mut self, aux: &EngineAux<ET>, c: ET::Char, lccode: ET::Char, globally: bool, )
Set the current lower case code \lccode for a character
Sourcefn get_uccode(&self, c: ET::Char) -> ET::Char
fn get_uccode(&self, c: ET::Char) -> ET::Char
Get the current upper case code \uccode for a character
Sourcefn set_uccode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
uccode: ET::Char,
globally: bool,
)
fn set_uccode( &mut self, aux: &EngineAux<ET>, c: ET::Char, uccode: ET::Char, globally: bool, )
Set the current upper case code \uccode for a character
Sourcefn get_delcode(&self, c: ET::Char) -> ET::Int
fn get_delcode(&self, c: ET::Char) -> ET::Int
Get the current delimiter code \delcode for a character
Sourcefn set_delcode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
delcode: ET::Int,
globally: bool,
)
fn set_delcode( &mut self, aux: &EngineAux<ET>, c: ET::Char, delcode: ET::Int, globally: bool, )
Set the current delimiter code \delcode for a character
Sourcefn get_mathcode(&self, c: ET::Char) -> u32
fn get_mathcode(&self, c: ET::Char) -> u32
Get the current math code \mathcode for a character
Sourcefn set_mathcode(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
mathcode: u32,
globally: bool,
)
fn set_mathcode( &mut self, aux: &EngineAux<ET>, c: ET::Char, mathcode: u32, globally: bool, )
Set the current math code \mathcode for a character
Sourcefn get_endline_char(&self) -> Option<ET::Char>
fn get_endline_char(&self) -> Option<ET::Char>
Get the current endline character
Sourcefn set_endline_char(
&mut self,
aux: &EngineAux<ET>,
c: Option<ET::Char>,
globally: bool,
)
fn set_endline_char( &mut self, aux: &EngineAux<ET>, c: Option<ET::Char>, globally: bool, )
Set the current endline character
Sourcefn get_escape_char(&self) -> Option<ET::Char>
fn get_escape_char(&self) -> Option<ET::Char>
Get the current escape character
Sourcefn set_escape_char(
&mut self,
aux: &EngineAux<ET>,
c: Option<ET::Char>,
globally: bool,
)
fn set_escape_char( &mut self, aux: &EngineAux<ET>, c: Option<ET::Char>, globally: bool, )
Set the current escape character
Sourcefn get_newline_char(&self) -> Option<ET::Char>
fn get_newline_char(&self) -> Option<ET::Char>
Get the current newline character
Sourcefn set_newline_char(
&mut self,
aux: &EngineAux<ET>,
c: Option<ET::Char>,
globally: bool,
)
fn set_newline_char( &mut self, aux: &EngineAux<ET>, c: Option<ET::Char>, globally: bool, )
Set the current newline character
Sourcefn get_parshape(&self) -> &Vec<(ET::Dim, ET::Dim)>
fn get_parshape(&self) -> &Vec<(ET::Dim, ET::Dim)>
Get the current \parshape
Sourcefn take_parshape(&mut self) -> Vec<(ET::Dim, ET::Dim)>
fn take_parshape(&mut self) -> Vec<(ET::Dim, ET::Dim)>
Get the current \parshape and set it to its default value
Sourcefn set_parshape(
&mut self,
aux: &EngineAux<ET>,
parshape: Vec<(ET::Dim, ET::Dim)>,
globally: bool,
)
fn set_parshape( &mut self, aux: &EngineAux<ET>, parshape: Vec<(ET::Dim, ET::Dim)>, globally: bool, )
Set the current \parshape
Sourcefn get_int_register(&self, idx: usize) -> ET::Int
fn get_int_register(&self, idx: usize) -> ET::Int
Get an integer register value
Sourcefn set_int_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: ET::Int,
globally: bool,
)
fn set_int_register( &mut self, aux: &EngineAux<ET>, idx: usize, v: ET::Int, globally: bool, )
Set an integer register value
Sourcefn get_primitive_int(&self, name: PrimitiveIdentifier) -> ET::Int
fn get_primitive_int(&self, name: PrimitiveIdentifier) -> ET::Int
Get a primitive integer value
Sourcefn set_primitive_int(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: ET::Int,
globally: bool,
)
fn set_primitive_int( &mut self, aux: &EngineAux<ET>, name: PrimitiveIdentifier, v: ET::Int, globally: bool, )
Set a primitive integer value
Sourcefn get_dim_register(&self, idx: usize) -> ET::Dim
fn get_dim_register(&self, idx: usize) -> ET::Dim
Get a dimen register value
Sourcefn set_dim_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: ET::Dim,
globally: bool,
)
fn set_dim_register( &mut self, aux: &EngineAux<ET>, idx: usize, v: ET::Dim, globally: bool, )
Set a dimen register value
Sourcefn get_skip_register(&self, idx: usize) -> Skip<ET::Dim>
fn get_skip_register(&self, idx: usize) -> Skip<ET::Dim>
Get a skip register value
Sourcefn set_skip_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: Skip<ET::Dim>,
globally: bool,
)
fn set_skip_register( &mut self, aux: &EngineAux<ET>, idx: usize, v: Skip<ET::Dim>, globally: bool, )
Set a skip register value
Sourcefn get_muskip_register(&self, idx: usize) -> MuSkip<ET::MuDim>
fn get_muskip_register(&self, idx: usize) -> MuSkip<ET::MuDim>
Get a muskip register value
Sourcefn set_muskip_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: MuSkip<ET::MuDim>,
globally: bool,
)
fn set_muskip_register( &mut self, aux: &EngineAux<ET>, idx: usize, v: MuSkip<ET::MuDim>, globally: bool, )
Set a muskip register value
Sourcefn get_toks_register(&self, idx: usize) -> &TokenList<ET::Token>
fn get_toks_register(&self, idx: usize) -> &TokenList<ET::Token>
Get a token register value
Sourcefn set_toks_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: TokenList<ET::Token>,
globally: bool,
)
fn set_toks_register( &mut self, aux: &EngineAux<ET>, idx: usize, v: TokenList<ET::Token>, globally: bool, )
Set a token register value
Sourcefn get_box_register(&self, idx: usize) -> Option<&TeXBox<ET>>
fn get_box_register(&self, idx: usize) -> Option<&TeXBox<ET>>
Get a box register value
Sourcefn get_box_register_mut(&mut self, idx: usize) -> Option<&mut TeXBox<ET>>
fn get_box_register_mut(&mut self, idx: usize) -> Option<&mut TeXBox<ET>>
Get a box register value mutably (to e.g. change \ht, \wd, \dp, etc.)
Sourcefn take_box_register(&mut self, idx: usize) -> Option<TeXBox<ET>>
fn take_box_register(&mut self, idx: usize) -> Option<TeXBox<ET>>
Take a box register value; replacing it with None (i.e. void box)
Sourcefn set_box_register(
&mut self,
aux: &EngineAux<ET>,
idx: usize,
v: Option<TeXBox<ET>>,
globally: bool,
)
fn set_box_register( &mut self, aux: &EngineAux<ET>, idx: usize, v: Option<TeXBox<ET>>, globally: bool, )
Set a box register value
Sourcefn get_primitive_dim(&self, name: PrimitiveIdentifier) -> ET::Dim
fn get_primitive_dim(&self, name: PrimitiveIdentifier) -> ET::Dim
Get a primitive dimension value
Sourcefn set_primitive_dim(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: ET::Dim,
globally: bool,
)
fn set_primitive_dim( &mut self, aux: &EngineAux<ET>, name: PrimitiveIdentifier, v: ET::Dim, globally: bool, )
Set a primitive dimension value
Sourcefn get_primitive_skip(&self, name: PrimitiveIdentifier) -> Skip<ET::Dim>
fn get_primitive_skip(&self, name: PrimitiveIdentifier) -> Skip<ET::Dim>
Get a primitive skip value
Sourcefn set_primitive_skip(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: Skip<ET::Dim>,
globally: bool,
)
fn set_primitive_skip( &mut self, aux: &EngineAux<ET>, name: PrimitiveIdentifier, v: Skip<ET::Dim>, globally: bool, )
Set a primitive skip value
Sourcefn get_primitive_muskip(&self, name: PrimitiveIdentifier) -> MuSkip<ET::MuDim>
fn get_primitive_muskip(&self, name: PrimitiveIdentifier) -> MuSkip<ET::MuDim>
Get a primitive muskip value
Sourcefn set_primitive_muskip(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: MuSkip<ET::MuDim>,
globally: bool,
)
fn set_primitive_muskip( &mut self, aux: &EngineAux<ET>, name: PrimitiveIdentifier, v: MuSkip<ET::MuDim>, globally: bool, )
Set a primitive muskip value
Sourcefn get_primitive_tokens(
&self,
name: PrimitiveIdentifier,
) -> &TokenList<ET::Token>
fn get_primitive_tokens( &self, name: PrimitiveIdentifier, ) -> &TokenList<ET::Token>
Get a primitive token list
Sourcefn set_primitive_tokens(
&mut self,
aux: &EngineAux<ET>,
name: PrimitiveIdentifier,
v: TokenList<ET::Token>,
globally: bool,
)
fn set_primitive_tokens( &mut self, aux: &EngineAux<ET>, name: PrimitiveIdentifier, v: TokenList<ET::Token>, globally: bool, )
Set a primitive token list
Sourcefn get_command(&self, name: &ET::CSName) -> Option<&TeXCommand<ET>>
fn get_command(&self, name: &ET::CSName) -> Option<&TeXCommand<ET>>
Get the current definition for the control sequence name
Sourcefn set_command(
&mut self,
aux: &EngineAux<ET>,
name: ET::CSName,
cmd: Option<TeXCommand<ET>>,
globally: bool,
)
fn set_command( &mut self, aux: &EngineAux<ET>, name: ET::CSName, cmd: Option<TeXCommand<ET>>, globally: bool, )
Set the current definition for the control sequence name
Sourcefn get_ac_command(&self, c: ET::Char) -> Option<&TeXCommand<ET>>
fn get_ac_command(&self, c: ET::Char) -> Option<&TeXCommand<ET>>
Get the current definition for the active character
Sourcefn set_ac_command(
&mut self,
aux: &EngineAux<ET>,
c: ET::Char,
cmd: Option<TeXCommand<ET>>,
globally: bool,
)
fn set_ac_command( &mut self, aux: &EngineAux<ET>, c: ET::Char, cmd: Option<TeXCommand<ET>>, globally: bool, )
Set the current definition for the active character
Provided Methods§
Sourcefn register_index(i: ET::Int) -> Option<usize>
fn register_index(i: ET::Int) -> Option<usize>
convert the provided integer value into a legal index for a register (or None if out of range)
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".