///Предварительный разбор void Prepare (const ParseNode& decl) { for (Parser::Iterator iter=decl.First (); iter; ++iter) { try { ParseNode decl = *iter; const char* type = decl.Name (); ParserMap::iterator iter = parsers.find (type); if (iter == parsers.end () || !iter->second.prepare_handler) continue; //игнорирование неизвестных узлов iter->second.prepare_handler (decl); } catch (common::ParserException&) { //игнорирование, протоколирование уже произведено } catch (std::exception& e) { root.Log ().Error (*iter, "%s", e.what ()); } catch (...) { root.Log ().Error (*iter, "unknown exception"); } } prepared = true; }
SpriteDeclPtr XmlSceneParser::Impl::PrepareSprite (const ParseNode& decl) { try { //попытка найти параметры в кеше if (SpriteDeclPtr* node_decl_ptr = cache.FindValue<SpriteDeclPtr> (decl)) return *node_decl_ptr; SpriteDeclPtr node_decl (new SpriteDecl, false); node_decl->color.Parse (decl, "color"); node_decl->alpha.Parse (decl, "alpha"); node_decl->mode.Parse (decl, "mode"); node_decl->usage.Parse (decl, "usage"); node_decl->up.Parse (decl, "up"); node_decl->material = get<const char*> (decl, "material", ""); if (ParseNode layout_node = decl.First ("layout")) node_decl->layout.reset (new stl::string (get<const char*> (layout_node, ""))); //регистрация дескриптора узла cache.SetValue (decl, node_decl); return node_decl; } catch (xtl::exception& e) { e.touch ("scene_graph::XmlSceneParser::Impl::PrepareSprite"); throw; } }
///Конструктор SceneRenderServerSubsystem (ParseNode& node) { const char* name = get<const char*> (node, "Id"); const char* threading_model_name = get<const char*> (node, "ThreadingModel", "SingleThreaded"); ServerThreadingModel threading_model = ServerThreadingModel_SingleThreaded; if (!strcmp (threading_model_name, "MultiThreaded")) threading_model = ServerThreadingModel_MultiThreaded; else if (!strcmp (threading_model_name, "SingleThreaded")) threading_model = ServerThreadingModel_SingleThreaded; else common::raise_parser_exception (node.First ("ThreadingModel"), "Invalid threading model '%s'", threading_model_name); const char *driver_mask = get<const char*> (node, "DriverMask", (const char*)0), *adapter_mask = get<const char*> (node, "AdapterMask", (const char*)0), *init_string = get<const char*> (node, "InitString", (const char*)0); server.reset (new Server (name, threading_model)); for (Parser::NamesakeIterator iter=node.First ("RenderTarget"); iter; ++iter) { const char* attachment = get<const char*> (*iter, "Window"); const char* name = get<const char*> (*iter, "Id", attachment); syslib::Window& window = AttachmentRegistry::Get<syslib::Window> (attachment); common::PropertyMap properties = to_properties (*iter); if (driver_mask) properties.SetProperty ("DriverMask", driver_mask); if (adapter_mask) properties.SetProperty ("AdapterMask", adapter_mask); if (init_string) properties.SetProperty ("InitString", init_string); server->AttachWindow (name, window, properties); } }
void XmlSceneParser::Parse (const ParseNode& decl, Node& parent, SceneContext& context) { try { for (Parser::Iterator iter=decl.First (); iter; ++iter) { try { ParseNode decl = *iter; const char* type = decl.Name (); Impl::ParserMap::iterator iter = impl->parsers.find (type); if (iter == impl->parsers.end () || !iter->second.parse_handler) continue; //игнорирование неизвестных узлов iter->second.parse_handler (decl, parent, context); } catch (std::exception& e) { if (!context.FilterError (e.what ())) throw; print_log (context.LogHandler (), e.what ()); } catch (...) { static const char* ERROR_STRING = "unknown exception"; if (!context.FilterError (ERROR_STRING)) throw; print_log (context.LogHandler (), ERROR_STRING); } } } catch (xtl::exception& e) { e.touch ("scene_graph::XmlSceneParser::ParseDispatch"); throw; } }
///Конструктор WindowInputDriverSubsystem (ParseNode& node) { for (Parser::NamesakeIterator iter=node.First ("Device"); iter; ++iter) devices.push_back (DevicePtr (new WindowDevice (*iter), false)); }
NodeDeclPtr XmlSceneParser::Impl::PrepareNode (const ParseNode& decl) { try { //попытка найти параметры в кеше if (NodeDeclPtr* node_decl_ptr = cache.FindValue<NodeDeclPtr> (decl)) return *node_decl_ptr; NodeDeclPtr node_decl (new NodeDecl, false); //парсинг базовых свойств node_decl->name = get<const char*> (decl, "id", ""); //парсинг точки поворота if (decl.First ("pivot")) { stl::auto_ptr<NodeDecl::Pivot> pivot (new NodeDecl::Pivot); ParseAttribute (decl, "pivot", pivot->position); pivot->has_orientation_pivot = strcmp (get<const char*> (decl, "orientation_pivot", "true"), "true") == 0; pivot->has_scale_pivot = strcmp (get<const char*> (decl, "scale_pivot", "true"), "true") == 0; node_decl->pivot = pivot; } //парсинг трансформаций node_decl->is_world_transform = strcmp (get<const char*> (decl, "bind_space", "local"), "world") == 0; if (ParseNode tm_node = decl.First ("transform")) { math::mat4f tm; ParseAttribute (tm_node, "", tm); affine_decompose (tm, node_decl->position, node_decl->orientation, node_decl->scale); } else { ParseAttribute (decl, "position", node_decl->position); ParseAttribute (decl, "scale", node_decl->scale); if (ParseNode rotation_node = decl.First ("rotation")) { float rotation [3] = {0.0f, 0.0f, 0.0f}; ParseAttribute (rotation_node, "", 3, &rotation [0]); node_decl->orientation = to_quat (degree (rotation [0]), degree (rotation [1]), degree (rotation [2])); } else { ParseAttribute (decl, "orientation", node_decl->orientation); } } node_decl->orientation_inherit = strcmp (get<const char*> (decl, "orientation_inherit", "true"), "true") == 0; node_decl->scale_inherit = strcmp (get<const char*> (decl, "scale_inherit", "true"), "true") == 0; //парсинг пользовательских свойств PropertyMap* properties = 0; if (decl.First ("property")) node_decl->properties.reset (properties = new PropertyMap); for (Parser::NamesakeIterator iter = decl.First ("property"); iter; ++iter) { ParseNode property_decl = *iter; const char* name = get<const char*> (property_decl, "name"); PropertyType type = get_property_type (property_decl.First ("type")); size_t property_index = properties->AddProperty (name, type, 1); stl::string value = get<const char*> (property_decl, "value"); properties->SetProperty (property_index, value.c_str ()); } //парсинг after node if (ParseNode before_node_decl = decl.First ("before_node")) { node_decl->before_node.reset (new stl::string); *node_decl->before_node = get<const char*> (before_node_decl, ""); } //парсинг привязки к родителю if (ParseNode parent_name_decl = decl.First ("parent")) { node_decl->parent_name.reset (new stl::string); *node_decl->parent_name = get<const char*> (parent_name_decl, ""); } //регистрация дескриптора узла cache.SetValue (decl, node_decl); return node_decl; } catch (xtl::exception& e) { e.touch ("scene_graph::XmlSceneParser::Impl::PrepareNode"); throw; } }