@@ -24,6 +24,11 @@ namespace mujoco::platform {
2424
2525SpecEditor::SpecEditor (int history_size) : capacity_(history_size) {}
2626
27+ void SpecEditor::Reset () {
28+ ref_spec_.reset ();
29+ active_spec_.reset ();
30+ }
31+
2732void SpecEditor::Reset (const mjSpec& spec) {
2833 active_element_key_ = kInvalidElementKey ;
2934 active_element_ = nullptr ;
@@ -55,6 +60,10 @@ void SpecEditor::Reset(const mjSpec& spec) {
5560}
5661
5762std::unique_ptr<ModelHolder> SpecEditor::Compile () {
63+ if (!active_spec_) {
64+ return nullptr ;
65+ }
66+
5867 auto holder = ModelHolder::FromSpec (mj_copySpec (active_spec_.get ()));
5968 if (holder->ok ()) {
6069 ref_spec_ = Copy (active_spec_.get ());
@@ -66,6 +75,10 @@ std::unique_ptr<ModelHolder> SpecEditor::Compile() {
6675mjSpec* SpecEditor::GetActiveSpec () const { return active_spec_.get (); }
6776
6877mjsElement* SpecEditor::AddElement (mjtObj type) {
78+ if (!active_spec_) {
79+ return nullptr ;
80+ }
81+
6982 // TODO: check that type is only for spec elements.
7083 mjsElement* element = AddElementToSpec (active_spec_.get (), type);
7184 if (element) {
@@ -82,6 +95,10 @@ mjsElement* SpecEditor::AddElement(mjtObj type) {
8295}
8396
8497mjsElement* SpecEditor::AddBodyElement (mjsBody* body, mjtObj type) {
98+ if (!active_spec_) {
99+ return nullptr ;
100+ }
101+
85102 // TODO: check that type is only for body elements.
86103 mjsElement* element = AddElementToSpec (active_spec_.get (), type, body);
87104 if (element) {
@@ -98,6 +115,10 @@ mjsElement* SpecEditor::AddBodyElement(mjsBody* body, mjtObj type) {
98115}
99116
100117void SpecEditor::DeleteActiveElement () {
118+ if (!active_spec_) {
119+ return ;
120+ }
121+
101122 if (active_element_) {
102123 const mjtObj type = active_element_->elemtype ;
103124 const int index = active_map_.Remove (active_element_key_);
@@ -116,6 +137,10 @@ void SpecEditor::DeleteActiveElement() {
116137}
117138
118139void SpecEditor::SetActiveElement (mjsElement* element) {
140+ if (!active_spec_) {
141+ return ;
142+ }
143+
119144 if (element == nullptr ) {
120145 ref_element_ = nullptr ;
121146 active_element_ = nullptr ;
@@ -152,6 +177,10 @@ void SpecEditor::SetActiveElement(mjsElement* element) {
152177}
153178
154179void SpecEditor::UpdateReferenceElement () {
180+ if (!active_spec_) {
181+ return ;
182+ }
183+
155184 if (active_element_ == nullptr ) {
156185 ref_element_ = nullptr ;
157186 } else {
@@ -175,6 +204,10 @@ mjsElement* SpecEditor::GetActiveElement() const { return active_element_; }
175204mjsElement* SpecEditor::GetRefElement () const { return ref_element_; }
176205
177206void SpecEditor::CommitChanges (mjsElement* element) {
207+ if (!active_spec_) {
208+ return ;
209+ }
210+
178211 if (element == nullptr ) {
179212 mju_warning (" Element is null." );
180213 return ;
@@ -233,6 +266,10 @@ void SpecEditor::Redo() {
233266bool SpecEditor::CanRedo () const { return cursor_ < history_.size () - 1 ; }
234267
235268void SpecEditor::AppendHistory (HistoryEntry entry) {
269+ if (!active_spec_) {
270+ return ;
271+ }
272+
236273 ++cursor_;
237274 while (history_.size () > cursor_) {
238275 history_.pop_back ();
0 commit comments