| | 1388 | |
| | 1389 | struct MyFindFileCallback : public osgDB::FindFileCallback |
| | 1390 | { |
| | 1391 | virtual std::string findDataFile(const std::string& filename, const osgDB::Options* options, osgDB::CaseSensitivity caseSensitivity) |
| | 1392 | { |
| | 1393 | osg::notify(osg::NOTICE)<<std::endl<<std::endl<<"find file "<<filename<<std::endl; |
| | 1394 | |
| | 1395 | const osgDB::FilePathList& paths = options ? options->getDatabasePathList() : osgDB::getDataFilePathList(); |
| | 1396 | |
| | 1397 | for(osgDB::FilePathList::const_iterator itr = paths.begin(); |
| | 1398 | itr != paths.end(); |
| | 1399 | ++itr) |
| | 1400 | { |
| | 1401 | const std::string& path = *itr; |
| | 1402 | std::string newpath = osgDB::concatPaths(path, filename); |
| | 1403 | if (osgDB::containsServerAddress(path)) |
| | 1404 | { |
| | 1405 | osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension("curl"); |
| | 1406 | osg::notify(osg::NOTICE)<<" file on server "<<*itr<<", try path "<<newpath<<std::endl; |
| | 1407 | osg::notify(osg::NOTICE)<<" we have curl rw= "<<rw<<std::endl; |
| | 1408 | if (rw && rw->fileExists(newpath, options)) |
| | 1409 | { |
| | 1410 | osg::notify(osg::NOTICE)<<" FOUND on server "<<newpath<<std::endl; |
| | 1411 | return newpath; |
| | 1412 | } |
| | 1413 | } |
| | 1414 | else |
| | 1415 | { |
| | 1416 | if(osgDB::fileExists(newpath)) |
| | 1417 | { |
| | 1418 | osg::notify(osg::NOTICE)<<" FOUND "<<newpath<<std::endl; |
| | 1419 | return newpath; |
| | 1420 | } |
| | 1421 | } |
| | 1422 | } |
| | 1423 | |
| | 1424 | return osgDB::Registry::instance()->findDataFileImplementation(filename, options, caseSensitivity); |
| | 1425 | } |
| | 1426 | }; |
| | 1427 | |
| | 1428 | class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback |
| | 1429 | { |
| | 1430 | public: |
| | 1431 | |
| | 1432 | osgDB::FilePathList _paths; |
| | 1433 | |
| | 1434 | typedef std::map< std::string, osg::ref_ptr<osg::Object> > ObjectCache; |
| | 1435 | |
| | 1436 | enum ObjectType |
| | 1437 | { |
| | 1438 | OBJECT, |
| | 1439 | IMAGE, |
| | 1440 | HEIGHT_FIELD, |
| | 1441 | NODE, |
| | 1442 | SHADER |
| | 1443 | }; |
| | 1444 | |
| | 1445 | osgDB::ReaderWriter::ReadResult readLocal(ObjectType type, const std::string& filename, const osgDB::Options* options) |
| | 1446 | { |
| | 1447 | osg::notify(osg::INFO)<<"Trying local file "<<filename<<std::endl; |
| | 1448 | |
| | 1449 | switch(type) |
| | 1450 | { |
| | 1451 | case(OBJECT): return osgDB::Registry::instance()->readObjectImplementation(filename,options); |
| | 1452 | case(IMAGE): return osgDB::Registry::instance()->readImageImplementation(filename,options); |
| | 1453 | case(HEIGHT_FIELD): return osgDB::Registry::instance()->readHeightFieldImplementation(filename,options); |
| | 1454 | case(NODE): return osgDB::Registry::instance()->readNodeImplementation(filename,options); |
| | 1455 | case(SHADER): return osgDB::Registry::instance()->readShaderImplementation(filename,options); |
| | 1456 | } |
| | 1457 | return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; |
| | 1458 | } |
| | 1459 | |
| | 1460 | |
| | 1461 | osgDB::ReaderWriter::ReadResult readFileCache(ObjectType type, const std::string& filename, const osgDB::Options* options) |
| | 1462 | { |
| | 1463 | |
| | 1464 | osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; |
| | 1465 | if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); |
| | 1466 | if (!fileCache) return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; |
| | 1467 | |
| | 1468 | osg::notify(osg::INFO)<<"Trying fileCache "<<filename<<std::endl; |
| | 1469 | |
| | 1470 | osgDB::ReaderWriter::ReadResult result; |
| | 1471 | if (fileCache && fileCache->isFileAppropriateForFileCache(filename)) |
| | 1472 | { |
| | 1473 | if (fileCache->existsInCache(filename)) |
| | 1474 | { |
| | 1475 | switch(type) |
| | 1476 | { |
| | 1477 | case(OBJECT): |
| | 1478 | result = fileCache->readObject(filename, 0); |
| | 1479 | break; |
| | 1480 | case(IMAGE): |
| | 1481 | result = fileCache->readImage(filename, 0); |
| | 1482 | break; |
| | 1483 | case(HEIGHT_FIELD): |
| | 1484 | result = fileCache->readHeightField(filename, 0); |
| | 1485 | break; |
| | 1486 | case(NODE): |
| | 1487 | result = fileCache->readNode(filename,0); |
| | 1488 | break; |
| | 1489 | case(SHADER): |
| | 1490 | result = fileCache->readShader(filename, 0); |
| | 1491 | break; |
| | 1492 | } |
| | 1493 | |
| | 1494 | if (result.success()) |
| | 1495 | { |
| | 1496 | osg::notify(osg::INFO)<<" File read from FileCache."<<std::endl; |
| | 1497 | return result; |
| | 1498 | } |
| | 1499 | |
| | 1500 | osg::notify(osg::NOTICE)<<" File in FileCache, but not successfully read"<<std::endl; |
| | 1501 | } |
| | 1502 | else |
| | 1503 | { |
| | 1504 | osg::notify(osg::INFO)<<" File does not exist in FileCache: "<<fileCache->createCacheFileName(filename)<<std::endl; |
| | 1505 | } |
| | 1506 | } |
| | 1507 | |
| | 1508 | return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; |
| | 1509 | |
| | 1510 | } |
| | 1511 | |
| | 1512 | osgDB::ReaderWriter::ReadResult readServer(ObjectType type, const std::string& filename, const osgDB::Options* options) |
| | 1513 | { |
| | 1514 | osg::notify(osg::INFO)<<"Trying server file "<<filename<<std::endl; |
| | 1515 | |
| | 1516 | osgDB::ReaderWriter::ReadResult result; |
| | 1517 | osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension("curl"); |
| | 1518 | if (!rw) return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; |
| | 1519 | |
| | 1520 | switch(type) |
| | 1521 | { |
| | 1522 | case(OBJECT): |
| | 1523 | result = rw->readObject(filename,options); |
| | 1524 | break; |
| | 1525 | case(IMAGE): |
| | 1526 | result = rw->readImage(filename,options); |
| | 1527 | break; |
| | 1528 | case(HEIGHT_FIELD): |
| | 1529 | result = rw->readHeightField(filename,options); |
| | 1530 | break; |
| | 1531 | case(NODE): |
| | 1532 | result = rw->readNode(filename,options); |
| | 1533 | break; |
| | 1534 | case(SHADER): |
| | 1535 | result = rw->readShader(filename,options); |
| | 1536 | break; |
| | 1537 | } |
| | 1538 | |
| | 1539 | if (result.success()) |
| | 1540 | { |
| | 1541 | osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; |
| | 1542 | if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); |
| | 1543 | |
| | 1544 | if (fileCache && fileCache->isFileAppropriateForFileCache(filename)) |
| | 1545 | { |
| | 1546 | switch(type) |
| | 1547 | { |
| | 1548 | case(OBJECT): |
| | 1549 | fileCache->writeObject(*result.getObject(),filename,options); |
| | 1550 | break; |
| | 1551 | case(IMAGE): |
| | 1552 | result.getImage()->setFileName(filename); |
| | 1553 | fileCache->writeImage(*result.getImage(),filename,options); |
| | 1554 | break; |
| | 1555 | case(HEIGHT_FIELD): |
| | 1556 | fileCache->writeHeightField(*result.getHeightField(),filename,options); |
| | 1557 | break; |
| | 1558 | case(NODE): |
| | 1559 | fileCache->writeNode(*result.getNode(),filename,options); |
| | 1560 | break; |
| | 1561 | case(SHADER): |
| | 1562 | fileCache->writeShader(*result.getShader(),filename,options); |
| | 1563 | break; |
| | 1564 | } |
| | 1565 | } |
| | 1566 | |
| | 1567 | return result; |
| | 1568 | } |
| | 1569 | return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; |
| | 1570 | } |
| | 1571 | |
| | 1572 | |
| | 1573 | osgDB::ReaderWriter::ReadResult read(const osgDB::FilePathList& filePathList, ObjectType type, const std::string& filename, const osgDB::Options* options, bool checkLocalFiles) |
| | 1574 | { |
| | 1575 | // go look in http paths |
| | 1576 | for(osgDB::FilePathList::const_iterator itr = filePathList.begin(); |
| | 1577 | itr != filePathList.end(); |
| | 1578 | ++itr) |
| | 1579 | { |
| | 1580 | const std::string& path = *itr; |
| | 1581 | std::string newpath = path.empty() ? filename : osgDB::concatPaths(path, filename); |
| | 1582 | osgDB::ReaderWriter::ReadResult result; |
| | 1583 | if (osgDB::containsServerAddress(newpath)) |
| | 1584 | { |
| | 1585 | if (checkLocalFiles) result = readFileCache(type, newpath, options); |
| | 1586 | else result = readServer(type, newpath, options); |
| | 1587 | } |
| | 1588 | else if (checkLocalFiles && osgDB::fileExists(newpath)) |
| | 1589 | { |
| | 1590 | result = readLocal(type, newpath, options); |
| | 1591 | } |
| | 1592 | |
| | 1593 | if (result.success()) |
| | 1594 | { |
| | 1595 | osg::notify(osg::INFO)<<" inserting object into file cache "<<filename<<", "<<result.getObject()<<std::endl; |
| | 1596 | _objectCache[filename] = result.getObject(); |
| | 1597 | |
| | 1598 | options->setPluginStringData("filename",newpath); |
| | 1599 | return result; |
| | 1600 | } |
| | 1601 | } |
| | 1602 | return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; |
| | 1603 | } |
| | 1604 | |
| | 1605 | osgDB::ReaderWriter::ReadResult read(ObjectType type, const std::string& filename, const osgDB::Options* options) |
| | 1606 | { |
| | 1607 | osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; |
| | 1608 | if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); |
| | 1609 | if (fileCache && !fileCache->isFileAppropriateForFileCache(filename)) fileCache = 0; |
| | 1610 | |
| | 1611 | osg::notify(osg::INFO)<<"reading file "<<filename<<std::endl; |
| | 1612 | ObjectCache::iterator itr = _objectCache.find(filename); |
| | 1613 | if (itr != _objectCache.end()) |
| | 1614 | { |
| | 1615 | // object is in cache, just retrieve it. |
| | 1616 | if (itr->second.valid()) |
| | 1617 | { |
| | 1618 | osg::notify(osg::INFO)<<"File retrieved from cache, filename="<<filename<<std::endl; |
| | 1619 | return itr->second.get(); |
| | 1620 | } |
| | 1621 | else |
| | 1622 | { |
| | 1623 | osg::notify(osg::INFO)<<"File failed to load previously, won't attempt a second time "<<filename<<std::endl; |
| | 1624 | return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; |
| | 1625 | } |
| | 1626 | } |
| | 1627 | |
| | 1628 | { |
| | 1629 | bool checkLocalFiles = true; |
| | 1630 | osgDB::ReaderWriter::ReadResult result = read(_paths, type, filename, options, checkLocalFiles); |
| | 1631 | if (result.success()) return result; |
| | 1632 | |
| | 1633 | if (options && !(options->getDatabasePathList().empty())) |
| | 1634 | { |
| | 1635 | result = read(options->getDatabasePathList(), type, filename, options, checkLocalFiles); |
| | 1636 | if (result.success()) return result; |
| | 1637 | } |
| | 1638 | |
| | 1639 | result = read(osgDB::Registry::instance()->getDataFilePathList(), type, filename, options, checkLocalFiles); |
| | 1640 | if (result.success()) return result; |
| | 1641 | } |
| | 1642 | |
| | 1643 | { |
| | 1644 | bool checkLocalFiles = false; |
| | 1645 | osgDB::ReaderWriter::ReadResult result = read(_paths, type, filename, options, checkLocalFiles); |
| | 1646 | if (result.success()) return result; |
| | 1647 | |
| | 1648 | if (options && !(options->getDatabasePathList().empty())) |
| | 1649 | { |
| | 1650 | result = read(options->getDatabasePathList(), type, filename, options, checkLocalFiles); |
| | 1651 | if (result.success()) return result; |
| | 1652 | } |
| | 1653 | |
| | 1654 | result = read(osgDB::Registry::instance()->getDataFilePathList(), type, filename, options, checkLocalFiles); |
| | 1655 | if (result.success()) return result; |
| | 1656 | } |
| | 1657 | |
| | 1658 | _objectCache[filename] = 0; |
| | 1659 | |
| | 1660 | return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; |
| | 1661 | } |
| | 1662 | |
| | 1663 | virtual osgDB::ReaderWriter::ReadResult readObject(const std::string& filename, const osgDB::Options* options) |
| | 1664 | { |
| | 1665 | return read(OBJECT, filename, options); |
| | 1666 | } |
| | 1667 | |
| | 1668 | virtual osgDB::ReaderWriter::ReadResult readImage(const std::string& filename, const osgDB::Options* options) |
| | 1669 | { |
| | 1670 | return read(IMAGE, filename, options); |
| | 1671 | } |
| | 1672 | |
| | 1673 | virtual osgDB::ReaderWriter::ReadResult readHeightField(const std::string& filename, const osgDB::Options* options) |
| | 1674 | { |
| | 1675 | return read(HEIGHT_FIELD, filename, options); |
| | 1676 | } |
| | 1677 | |
| | 1678 | virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& filename, const osgDB::Options* options) |
| | 1679 | { |
| | 1680 | return read(NODE, filename, options); |
| | 1681 | } |
| | 1682 | |
| | 1683 | virtual osgDB::ReaderWriter::ReadResult readShader(const std::string& filename, const osgDB::Options* options) |
| | 1684 | { |
| | 1685 | return read(SHADER, filename, options); |
| | 1686 | } |
| | 1687 | |
| | 1688 | protected: |
| | 1689 | virtual ~MyReadFileCallback() {} |
| | 1690 | |
| | 1691 | ObjectCache _objectCache; |
| | 1692 | }; |
| | 1693 | |