From e48ac7f43584889925c569e432dbcec47fd11a18 Mon Sep 17 00:00:00 2001 From: floralrainfall Date: Tue, 18 Jul 2023 20:54:41 -0400 Subject: [PATCH] fix InstanceFactory for World::load --- .../RNR/textures/studio/icons/PointLight.png | Bin 0 -> 1124 bytes .../RNR/textures/studio/icons/RunService.png | Bin 0 -> 770 bytes Content/RNR/textures/studio/icons/pause.png | Bin 0 -> 733 bytes Content/RNR/textures/studio/icons/run.png | Bin 0 -> 912 bytes Projects/Client/CMakeLists.txt | 4 ++ Projects/Client/Studio/Header/MainWindow.hpp | 2 + Projects/Client/Studio/Source/MainWindow.cpp | 13 ++++ .../Client/Studio/Source/PropertyViewer.cpp | 11 ++- Projects/Engine/CMakeLists.txt | 2 + .../Header/App/Script/ReflectionProperty.hpp | 2 + .../Engine/Header/App/V8/DataModel/Camera.hpp | 2 +- .../Header/App/V8/DataModel/DataModel.hpp | 1 + .../Header/App/V8/DataModel/RunService.hpp | 29 ++++++++ .../Engine/Header/App/V8/Tree/Instance.hpp | 2 +- Projects/Engine/Header/App/V8/World/World.hpp | 13 +++- .../Source/App/V8/DataModel/DataModel.cpp | 17 ++++- .../Source/App/V8/DataModel/PartInstance.cpp | 3 +- .../Source/App/V8/DataModel/RunService.cpp | 52 +++++++++++++++ .../Source/App/V8/DataModel/Workspace.cpp | 2 + .../Engine/Source/App/V8/Tree/Instance.cpp | 4 +- Projects/Engine/Source/App/V8/World/World.cpp | 63 +++++++----------- 21 files changed, 174 insertions(+), 48 deletions(-) create mode 100644 Content/RNR/textures/studio/icons/PointLight.png create mode 100644 Content/RNR/textures/studio/icons/RunService.png create mode 100644 Content/RNR/textures/studio/icons/pause.png create mode 100644 Content/RNR/textures/studio/icons/run.png create mode 100644 Projects/Engine/Header/App/V8/DataModel/RunService.hpp create mode 100644 Projects/Engine/Source/App/V8/DataModel/RunService.cpp diff --git a/Content/RNR/textures/studio/icons/PointLight.png b/Content/RNR/textures/studio/icons/PointLight.png new file mode 100644 index 0000000000000000000000000000000000000000..c23f4219b4757c30f52c6d3b0252a24814420a95 GIT binary patch literal 1124 zcmV-q1e^PbP)EX>4Tx04R}tkv&MmKpe$iQ>7yH1MMKf)s6A|?JWDYS_3;J6>}?mh0_0Yam~RI@7vsG4P@ z6LB${TNMMZ2%sNBh+U4&e3JS*_Gq>z@3D!MwJz%ypV$NMI35NI`^*8p^1^LWEY06ccIMk9+t>9e;{kGP%lN zIZc;D~bidg4$2bt!1)6o+{yw(t<_X|`2ClTWzuEwzpQP8@ zTKEVU*aj}H+nT%wT$gU400009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-~x6954s`(o8z0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbP zPDw;TR5;6plD}&caTvy*yG!mzIP;@Dl$fC^Jwb<3oCKi|+@q6&h<|_}I5-qCcXE&* zVnh%Gr+|haN|BlaBc?+KA+c6PLe8c(n&i^va{1n`?>V(dNa{1aJUs7bc;AP?1ZkQ! z2OtMv6954)0`MfAPWQ*Np>bntYimK0q>V%(5te27isLw_*XtMz1}6aA#ZlVc-d-Gy zMt(3R-}i&{^>tsQzum*+!$WHWdJ1 zK@`Pfbgu>bP3F*aD>uQ2XYlRgD-c3HO$Bs1o%79R6KpI61Qgs{8s6qpFwu)3g9f@b z4_()5Qvua#RVx;YLrN*w#3lIOUxHs+0l&0@onC<5cH1>g^U+j5CX@LYkH>Ep% zhG5$^1VO-#uYl(dqaUU<@ww-D$(fm%Yn0M?00@Ob@H`Iy(C_!5D9Q@}_x}ZO2ScS& zA*ob~4~N6iNF=h@>-At+7A1r*gb+xQv}qW|^;|CZXX+6Pg~DpL+x=x2hNUP96h&bb zMFGcg-FCbEWq*HvH2wu{+^E;tu{e&~NG6k+d_Lctl>H0X_8qt`3@pw70000EX>4Tx04R}tkv&MmKpe$iQ>7yH1MMKf)s6A|?JWDYS_3;J6>}?mh0_0Yam~RI@7vsG4P@ z6LB${TNMMZ2%sNBh+U4&e3JS*_Gq>z@3D!MwJz%ypV$NMI35NI`^*8p^1^LWEY06ccIMk9+t>9e;{kGP%lN zIZc;D~bidg4$2bt!1)6o+{yw(t<_X|`2ClTWzuEwzpQP8@ zTKEVU*aj}H+nT%wT$gU400009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-~x5*IBPrHZxE0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN z>`6pHR5;6>(y>YdK@^4If3ubf5d{kgSl9?Yl_1#Ih`~-Qf~BRe;%i8Z1~qCEQV0P{ z3(aq_vt(JBWHxu|^X=X_1JXqfk(`xA?vXF#7TM3tT1|mIA~Hj!$PKcGv{HeG09b)O zk!xgkIV6J`P=zMQC9;ELG2k%*l;;=uK+ch^|ByT_0jkgoa*DKb^Q;7hi9mUN!e1XF z>uV6(Ejl@H09*mzAkPiHUS4bu=@bnWd!_6@4vo~RmDhv@F5*?nC~{FFN09dd+hGz%8<2dnu5R7CR?g8%>k07*qoM6N<$g0lKf AJ^%m! literal 0 HcmV?d00001 diff --git a/Content/RNR/textures/studio/icons/pause.png b/Content/RNR/textures/studio/icons/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..c54f68670280ae99cf5ddf83443dea014938eb58 GIT binary patch literal 733 zcmV<30wVp1P)EX>4Tx04R}tkv&MmKpe$iQ>7yH1MMKf)s6A|?JWDYS_3;J6>}?mh0_0Yam~RI@7vsG4P@ z6LB${TNMMZ2%sNBh+U4&e3JS*_Gq>z@3D!MwJz%ypV$NMI35NI`^*8p^1^LWEY06ccIMk9+t>9e;{kGP%lN zIZc;D~bidg4$2bt!1)6o+{yw(t<_X|`2ClTWzuEwzpQP8@ zTKEVU*aj}H+nT%wT$gU400009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-~x5*H#lZhN^y0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN z$4Nv%R9M69l|c#uAsB@}$ANLzx|_{Gy1?u@Mu+JZ18v&`K~&H{{cT)`ROrmmH0BS2 zq7NURPgOW2umWn{*9GWozfrJtv>Moa&>pPzs9^nag+L=9fvxtmWuR{7>I%<8L3mY+ zQ2vH`fB_Y#d;Bzk7z3u~p6L+iYe4>EX>4Tx04R}tkv&MmKpe$iQ>7yH1MMKf)s6A|?JWDYS_3;J6>}?mh0_0Yam~RI@7vsG4P@ z6LB${TNMMZ2%sNBh+U4&e3JS*_Gq>z@3D!MwJz%ypV$NMI35NI`^*8p^1^LWEY06ccIMk9+t>9e;{kGP%lN zIZc;D~bidg4$2bt!1)6o+{yw(t<_X|`2ClTWzuEwzpQP8@ zTKEVU*aj}H+nT%wT$gU400009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-~x5*H#nfOXh!0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbO zdPzhc-tUp*sc5$!$! zR!RV@9ud=sxDSBUG5}T&2BbAgfVF=BtZor$L@Ww`^%?-IZV+kL02_4xSY09}Tmfu` z0I(_|MjHj#Y5>5hfEWs6-vUk^)+BI+$RbkpCa~=wfl_@Nkba*D1pk=^?hs3e-f9W# zI8Gp_PXm(ll|b;c0n@-eVjj^IOkg+S1cG`qAPEbw=NZ822{Gm43d)^pU5h#0R{2M!`IE+9r~EyafpOK=V`TyHNpa#Z^V!?xq&kj7tT zqE0nB51fRk?HR;?tBELIXH)5OJrfqH7=IuZ5j|0j<);;l-;HrH>c!-&LbvMnwVIt9 m;}^4_cKTjUv&Oh7EBX&hH0vu&mgKhp0000addAction("Load", this, SLOT(loadDatamodel())); QMenu* help_menu = menubar->addMenu("Help"); help_menu->addAction("About..."); + + QAction* run_action = toolbar->addAction(QIcon("content/textures/studio/icons/run.png"), "", this, SLOT(run())); + QAction* pause_action = toolbar->addAction(QIcon("content/textures/studio/icons/pause.png"), "", this, SLOT(pause())); +} + +void MainWindow::run() +{ + this->ogreWidget->world->getRunService()->run(); +} + +void MainWindow::pause() +{ + this->ogreWidget->world->getRunService()->pause(); } void MainWindow::closeEvent(QCloseEvent* event) diff --git a/Projects/Client/Studio/Source/PropertyViewer.cpp b/Projects/Client/Studio/Source/PropertyViewer.cpp index f548ad4..2f09d6d 100644 --- a/Projects/Client/Studio/Source/PropertyViewer.cpp +++ b/Projects/Client/Studio/Source/PropertyViewer.cpp @@ -45,6 +45,15 @@ void PropertyViewer::view(RNR::Instance* instance) QTableWidgetItem* new_property_itemval = new QTableWidgetItem(tr("%1").arg(property.toString().c_str())); new_property_itemval->setToolTip(QString(property.description().c_str())); + if(property.op() == RNR::OPERATION_READ) + { + cell_flags = new_property_itemval->flags(); + cell_flags.setFlag(Qt::ItemFlag::ItemIsEditable, false); + cell_flags.setFlag(Qt::ItemFlag::ItemIsEnabled, false); + new_property_itemval->setFlags(cell_flags); + new_property_item->setFlags(cell_flags); + } + switch(property.type()) { case RNR::PROPERTY_BOOL: @@ -52,7 +61,7 @@ void PropertyViewer::view(RNR::Instance* instance) bool check_state = *(bool*)property.rawGetter(); new_property_itemval->setCheckState(check_state ? Qt::Checked : Qt::Unchecked); new_property_itemval->setText(""); - + cell_flags = new_property_itemval->flags(); cell_flags.setFlag(Qt::ItemFlag::ItemIsEditable, false); new_property_itemval->setFlags(cell_flags); diff --git a/Projects/Engine/CMakeLists.txt b/Projects/Engine/CMakeLists.txt index 0abd61d..f5a97e4 100644 --- a/Projects/Engine/CMakeLists.txt +++ b/Projects/Engine/CMakeLists.txt @@ -14,6 +14,7 @@ add_library(Engine STATIC Header/App/V8/DataModel/ForceField.hpp Header/App/V8/DataModel/PartInstance.hpp Header/App/V8/DataModel/FaceInstance.hpp + Header/App/V8/DataModel/RunService.hpp Header/App/V8/DataModel/Workspace.hpp Header/App/V8/Tree/Instance.hpp Header/App/V8/Tree/InstanceFactory.hpp @@ -40,6 +41,7 @@ add_library(Engine STATIC Source/App/V8/DataModel/ForceField.cpp Source/App/V8/DataModel/PartInstance.cpp Source/App/V8/DataModel/FaceInstance.cpp + Source/App/V8/DataModel/RunService.cpp Source/App/V8/DataModel/Workspace.cpp Source/App/V8/Tree/Instance.cpp Source/App/V8/Tree/InstanceFactory.cpp diff --git a/Projects/Engine/Header/App/Script/ReflectionProperty.hpp b/Projects/Engine/Header/App/Script/ReflectionProperty.hpp index f2ee8d1..56d2231 100644 --- a/Projects/Engine/Header/App/Script/ReflectionProperty.hpp +++ b/Projects/Engine/Header/App/Script/ReflectionProperty.hpp @@ -71,6 +71,8 @@ namespace RNR std::string name() { return m_name; } std::string description() { return m_description; } ReflectionPropertyType type() { return m_type; } + ReflectionPropertyAccess accessLevel() { return m_access; } + ReflectionPropertyOperation op() { return m_op; } const void* rawGetter() { return m_getter(m_object); } void rawSetter(const void* value) { return m_setter((void*)m_object, value); } diff --git a/Projects/Engine/Header/App/V8/DataModel/Camera.hpp b/Projects/Engine/Header/App/V8/DataModel/Camera.hpp index 2f0d8b5..2f4db1b 100644 --- a/Projects/Engine/Header/App/V8/DataModel/Camera.hpp +++ b/Projects/Engine/Header/App/V8/DataModel/Camera.hpp @@ -13,7 +13,7 @@ namespace RNR private: CoordinateFrame m_cframe; virtual void deserializeProperty(char* prop_name, pugi::xml_node prop); - virtual void addProperties(std::vector& properties); + virtual void addProperties(std::vector& properties); public: Camera(); ~Camera(); diff --git a/Projects/Engine/Header/App/V8/DataModel/DataModel.hpp b/Projects/Engine/Header/App/V8/DataModel/DataModel.hpp index 1f0a85c..f890073 100644 --- a/Projects/Engine/Header/App/V8/DataModel/DataModel.hpp +++ b/Projects/Engine/Header/App/V8/DataModel/DataModel.hpp @@ -8,6 +8,7 @@ namespace RNR public: DataModel(); + Instance* getService(std::string service_name); private: }; diff --git a/Projects/Engine/Header/App/V8/DataModel/RunService.hpp b/Projects/Engine/Header/App/V8/DataModel/RunService.hpp new file mode 100644 index 0000000..01628e6 --- /dev/null +++ b/Projects/Engine/Header/App/V8/DataModel/RunService.hpp @@ -0,0 +1,29 @@ +#pragma once +#include + +namespace RNR +{ + class RunService : public Instance + { + private: + float m_time; + + bool m_running; + bool m_paused; + + virtual void addProperties(std::vector& properties); + public: + RunService(); + + virtual std::string getClassName() { return "RunService"; } + + bool getRunning() { return m_running; } + bool getPaused() { return m_paused; } + + void step(float delta); + + void run(); + void pause(); + void reset(); + }; +} \ No newline at end of file diff --git a/Projects/Engine/Header/App/V8/Tree/Instance.hpp b/Projects/Engine/Header/App/V8/Tree/Instance.hpp index a0a7a60..e1cb17f 100644 --- a/Projects/Engine/Header/App/V8/Tree/Instance.hpp +++ b/Projects/Engine/Header/App/V8/Tree/Instance.hpp @@ -36,7 +36,7 @@ namespace RNR ~Instance(); virtual std::vector getProperties(); - void deserializeXmlProperty(pugi::xml_node prop); + void deserializeXmlProperty(pugi::xml_node prop); // TODO: eventually replace this with a method that uses getProperties bool contains(RNR::Instance* child); bool isAncestorOf(RNR::Instance* instance); diff --git a/Projects/Engine/Header/App/V8/World/World.hpp b/Projects/Engine/Header/App/V8/World/World.hpp index a778d25..339681c 100644 --- a/Projects/Engine/Header/App/V8/World/World.hpp +++ b/Projects/Engine/Header/App/V8/World/World.hpp @@ -1,8 +1,11 @@ #pragma once #include +#include #include #include +#include +#include #include #include #include @@ -21,11 +24,13 @@ namespace RNR private: std::map m_refs; std::stack m_undeserialized; - Instance* m_datamodel; + DataModel* m_datamodel; Workspace* m_workspace; + RunService* m_runService; Ogre::Root* m_ogreRoot; Ogre::SceneManager* m_ogreSceneManager; TopMenuBar* m_tmb; + InstanceFactory* m_instanceFactory; void xmlAddItem(pugi::xml_node node, Instance* parent); public: @@ -42,10 +47,12 @@ namespace RNR - Instance* getDatamodel() { return m_datamodel; } - void setDatamodel(Instance* instance) { m_datamodel = instance; } + DataModel* getDatamodel() { return m_datamodel; } + void setDatamodel(DataModel* instance) { m_datamodel = instance; } Workspace* getWorkspace() { return m_workspace; } void setWorkspace(Workspace* workspace) { m_workspace = workspace; } + RunService* getRunService() { return m_runService; } + void setRunService(RunService* runService) { m_runService = runService; } Ogre::Root* getOgreRoot() { return m_ogreRoot; } Ogre::SceneManager* getOgreSceneManager() { return m_ogreSceneManager; } }; diff --git a/Projects/Engine/Source/App/V8/DataModel/DataModel.cpp b/Projects/Engine/Source/App/V8/DataModel/DataModel.cpp index 2f89d72..d6ee9e6 100644 --- a/Projects/Engine/Source/App/V8/DataModel/DataModel.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/DataModel.cpp @@ -1,9 +1,24 @@ #include +#include namespace RNR { DataModel::DataModel() { - + + } + + Instance* DataModel::getService(std::string service_name) + { + Instance* service = findFirstChildOfType(service_name); + if(!service) + { + service = InstanceFactory::singleton()->build(service_name); + if(service) + { + service->setParent(this); + } + } + return service; } } diff --git a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp index bb69135..8ef18f8 100644 --- a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp @@ -8,8 +8,9 @@ namespace RNR { setName("Part"); - updateMatrix(); m_color = Ogre::Vector4(0.63, 0.64, 0.63, 1.0); + + updateMatrix(); } void PartInstance::updateMatrix() diff --git a/Projects/Engine/Source/App/V8/DataModel/RunService.cpp b/Projects/Engine/Source/App/V8/DataModel/RunService.cpp new file mode 100644 index 0000000..9c4c5bd --- /dev/null +++ b/Projects/Engine/Source/App/V8/DataModel/RunService.cpp @@ -0,0 +1,52 @@ +#include + +namespace RNR +{ + RunService::RunService() + { + setName("RunService"); + m_time = 0; + m_running = false; + m_paused = false; + } + + void RunService::step(float time) + { + if(m_running && !m_paused) + { + m_time += time; + } + } + + void RunService::run() + { + m_running = true; + m_paused = false; + } + + void RunService::reset() + { + + } + + void RunService::pause() + { + m_paused = true; + } + + void RunService::addProperties(std::vector& properties) + { + ReflectionProperty _properties[] = { + { this, std::string("Running"), std::string(""), + ACCESS_NONE, OPERATION_READ, PROPERTY_BOOL, + REFLECTION_GETTER(RunService* instance = (RunService*)object; return &instance->m_running; ), + REFLECTION_SETTER( ) }, // do nothing + { this, std::string("Paused"), std::string(""), + ACCESS_NONE, OPERATION_READ, PROPERTY_BOOL, + REFLECTION_GETTER(RunService* instance = (RunService*)object; return &instance->m_paused; ), + REFLECTION_SETTER( ) }, // do nothing + }; + + properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty))); + } +} \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp b/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp index 4e05125..fcd8170 100644 --- a/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp @@ -18,6 +18,8 @@ namespace RNR { Ogre::SubEntity* surface = m_partEntity->getSubEntity(i); Ogre::TextureUnitState* texture = surface->getMaterial()->getTechnique(0)->getPass(0)->createTextureUnitState("textures/stud_top.png"); + + surface->getMaterial()->setShininess(1.0); } } diff --git a/Projects/Engine/Source/App/V8/Tree/Instance.cpp b/Projects/Engine/Source/App/V8/Tree/Instance.cpp index a10e6ed..3246090 100644 --- a/Projects/Engine/Source/App/V8/Tree/Instance.cpp +++ b/Projects/Engine/Source/App/V8/Tree/Instance.cpp @@ -162,7 +162,9 @@ namespace RNR bool Instance::isA(std::string type) { - if (type == getClassName()); // TODO: check if type is any of parent types + if (type == getClassName()) + return true; // TODO: check if type is any of parent types + return false; } Instance* Instance::findFirstChild(std::string name) diff --git a/Projects/Engine/Source/App/V8/World/World.cpp b/Projects/Engine/Source/App/V8/World/World.cpp index df8e70b..bf4e673 100644 --- a/Projects/Engine/Source/App/V8/World/World.cpp +++ b/Projects/Engine/Source/App/V8/World/World.cpp @@ -12,23 +12,26 @@ namespace RNR { Instance::setWorld(this); + m_instanceFactory = new InstanceFactory(); + + m_instanceFactory->registerInstance("Camera", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("Model", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("SelectionBox", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("Part", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("Workspace", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("Humanoid", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("RunService", InstanceFactory::instanceBuilder); + m_ogreRoot = ogre; m_ogreSceneManager = ogreSceneManager; - m_datamodel = new Instance(); + m_datamodel = new DataModel(); m_datamodel->setName("DataModel"); - m_workspace = new Workspace(); - m_workspace->setParent(m_datamodel); - - InstanceFactory(); - - InstanceFactory::singleton()->registerInstance("Camera", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("Model", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("SelectionBox", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("Part", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("Workspace", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("Humanoid", InstanceFactory::instanceBuilder); + m_workspace = (Workspace*)m_datamodel->getService("Workspace"); + m_runService = (RunService*)m_datamodel->getService("RunService"); m_tmb = new TopMenuBar(); + + } World::~World() @@ -42,39 +45,19 @@ namespace RNR Instance* instance; - /* try{ - instance = InstanceFactory::singleton()->build(class_attr.as_string()); + if(parent == m_datamodel && m_datamodel->findFirstChildOfType(class_attr.as_string())) + instance = m_datamodel->findFirstChildOfType(class_attr.as_string()); + else + { + std::string class_name = class_attr.value(); + instance = m_instanceFactory->build(class_name); + } } catch(std::runtime_error e) { printf("World::xmlAddItem: InstanceFactory::build failed '%s'\n", e.what()); return; - }*/ - - if(class_attr.as_string() == std::string("Part")) - { - instance = new PartInstance(); - } - else if(class_attr.as_string() == std::string("Workspace")) - { - instance = m_workspace; - } - else if(class_attr.as_string() == std::string("Camera")) - { - instance = new Camera(); - } - else if(class_attr.as_string() == std::string("Model")) - { - instance = new ModelInstance(); - } - else if(class_attr.as_string() == std::string("Humanoid")) - { - instance = new Humanoid(); - } - else - { - instance = new Instance(); } pugi::xml_attribute referent = node.attribute("referent"); @@ -137,6 +120,8 @@ namespace RNR double World::step(float timestep) { + if(m_runService && m_runService->getRunning()) + m_runService->step(timestep); return 0.0; }