LoadingTrackingProcessor.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Serialization/SerializeContext.h>
  9. #include <Processors/LoadingTrackingProcessor.h>
  10. #include <SceneAPI/SceneCore/Utilities/Reporting.h>
  11. namespace SceneLoggingExample
  12. {
  13. LoadingTrackingProcessor::LoadingTrackingProcessor()
  14. {
  15. // For details about the CallProcessorBus and CallProcessorBinder, see ExportTrackingProcessor.cpp.
  16. BindToCall(&LoadingTrackingProcessor::ContextCallback, AZ::SceneAPI::Events::CallProcessorBinder::TypeMatch::Derived);
  17. }
  18. // Reflection is a basic requirement for components. For Loading components, you can often keep the Reflect() function
  19. // simple because the SceneAPI just needs to be able to find the component. For more details on the Reflect() function,
  20. // see LoggingGroup.cpp.
  21. void LoadingTrackingProcessor::Reflect(AZ::ReflectContext* context)
  22. {
  23. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  24. if (serializeContext)
  25. {
  26. serializeContext->Class<LoadingTrackingProcessor, AZ::SceneAPI::SceneCore::LoadingComponent>()->Version(1);
  27. }
  28. }
  29. // Later in this example, we will listen to and log messages that relate to file loading.
  30. // Before this can happen, we must connect to the bus that sends the messages.
  31. void LoadingTrackingProcessor::Activate()
  32. {
  33. AZ::SceneAPI::Events::AssetImportRequestBus::Handler::BusConnect();
  34. // Forward the call to the LoadingComponent so that the call bindings get activated.
  35. AZ::SceneAPI::SceneCore::LoadingComponent::Activate();
  36. }
  37. // Disconnect from the bus upon deactivation.
  38. void LoadingTrackingProcessor::Deactivate()
  39. {
  40. AZ::SceneAPI::SceneCore::LoadingComponent::Deactivate();
  41. // Forward the call to the LoadingComponent so that the call bindings get deactivated.
  42. AZ::SceneAPI::Events::CallProcessorBus::Handler::BusDisconnect();
  43. AZ::SceneAPI::Events::AssetImportRequestBus::Handler::BusDisconnect();
  44. }
  45. // Loading starts by announcing that loading will begin shortly. This provides an opportunity to prepare
  46. // caches or to take any additional steps that are required before loading.
  47. AZ::SceneAPI::Events::ProcessingResult LoadingTrackingProcessor::PrepareForAssetLoading(AZ::SceneAPI::Containers::Scene& /*scene*/,
  48. RequestingApplication /*requester*/)
  49. {
  50. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Preparing to load a scene.");
  51. // This function doesn't contribute anything to the loading, so let the SceneAPI know that it can ignore its contributions.
  52. return AZ::SceneAPI::Events::ProcessingResult::Ignored;
  53. }
  54. // After a call to PrepareForAssetLoading has been dispatched, the scene file (for example, .fbx) will be loaded.
  55. // This is normally what scene builders will be looking for. If the file has an extension that a scene builder
  56. // understands, it will start reading the source file, convert the data, and store it in the scene. This is also
  57. // true for loading the manifest file, which happens in this same pass.
  58. //
  59. // For this example, nothing is done because there's no data to read. We just echo the steps that are taken.
  60. AZ::SceneAPI::Events::LoadingResult LoadingTrackingProcessor::LoadAsset(AZ::SceneAPI::Containers::Scene& /*scene*/,
  61. [[maybe_unused]] const AZStd::string& path, const AZ::Uuid& /*guid*/, RequestingApplication /*requester*/)
  62. {
  63. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Loading scene from '%s'.", path.c_str());
  64. return AZ::SceneAPI::Events::LoadingResult::Ignored;
  65. }
  66. // After the scene file and manifest are loaded, we finalize the loading by making two calls: first to FinalizeAssetLoading()
  67. // and then to UpdateManifest().
  68. //
  69. // FinalizeAssetLoading() is the best time to close out any temporary buffers, clear cache, patch pointers, and any
  70. // other final steps that are required to put the graph in a valid state and perform any necessary cleanup.
  71. // We also disconnect from the Call Processor bus so that we won't receive export events later. It is possible to
  72. // make updates to the manifest in FinalizeAssetLoading(), but UpdateManifest() is a better place to do this.
  73. void LoadingTrackingProcessor::FinalizeAssetLoading(AZ::SceneAPI::Containers::Scene& /*scene*/, RequestingApplication /*requester*/)
  74. {
  75. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Finished loading scene.");
  76. }
  77. // UpdateManifest() provides additional information about the state of the manifest, such as if a default manifest is being
  78. // built or an existing one is being updated. The SceneGraph is ready at this point, so this function can be used to create a
  79. // new manifest or make corrections to an existing one.
  80. AZ::SceneAPI::Events::ProcessingResult LoadingTrackingProcessor::UpdateManifest(AZ::SceneAPI::Containers::Scene& /*scene*/, ManifestAction action,
  81. RequestingApplication /*requester*/)
  82. {
  83. switch (action)
  84. {
  85. case ManifestAction::ConstructDefault:
  86. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Constructing a new manifest.");
  87. break;
  88. case ManifestAction::Update:
  89. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Updating the manifest.");
  90. break;
  91. default:
  92. AZ_TracePrintf(AZ::SceneAPI::Utilities::WarningWindow, "Unknown manifest update action.");
  93. break;
  94. }
  95. return AZ::SceneAPI::Events::ProcessingResult::Ignored;
  96. }
  97. // With the SceneAPI, the order in which an EBus calls its listeners is mostly random. This generally isn't a problem because most work
  98. // is done in isolation. If there is a dependency, we recommend that you break a call into multiple smaller calls, but this isn't always
  99. // an option. For example, perhaps there is no source code available for third-party extensions or you are trying to avoid making code
  100. // changes to the engine/editor. For those situations, the Call Processor allows you to specify a priority to make sure that a call is made
  101. // before or after all other listeners have done their work.
  102. //
  103. // In this example, we want the log messages to be printed before any other listeners do their work and potentially print their data.
  104. // To accomplish this, we set the priority to the highest available number.
  105. uint8_t LoadingTrackingProcessor::GetPriority() const
  106. {
  107. return EarliestProcessing;
  108. }
  109. // In the constructor, this function was bound to accept any contexts that are derived from ICallContext, which is the base
  110. // for all CallProcessorBus events. This allows for monitoring of everything that happens during the loading process.
  111. AZ::SceneAPI::Events::ProcessingResult LoadingTrackingProcessor::ContextCallback([[maybe_unused]] AZ::SceneAPI::Events::ICallContext& context)
  112. {
  113. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "LoadEvent: %s", context.RTTI_GetTypeName());
  114. return AZ::SceneAPI::Events::ProcessingResult::Ignored;
  115. }
  116. } // namespace SceneLoggingExample