ApplePickerComponent.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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 "ApplePickerComponent.h"
  9. #include "ApplePickingRequests.h"
  10. #include <AzCore/EBus/Event.h>
  11. #include <AzCore/Serialization/EditContext.h>
  12. #include <AzCore/Serialization/EditContextConstants.inl>
  13. namespace AppleKraken
  14. {
  15. namespace Internal
  16. {
  17. AZStd::string TaskString(const PickAppleTask& task)
  18. {
  19. if (!task.m_appleEntityId.IsValid())
  20. {
  21. return "|Task for an unspecified apple|";
  22. }
  23. return AZStd::string::format("|Task for entity id %s|", task.m_appleEntityId.ToString().c_str());
  24. }
  25. AZStd::string CurrentTaskString(const AZStd::queue<PickAppleTask>& taskQueue)
  26. {
  27. if (taskQueue.empty())
  28. {
  29. return "|No task, pick queue empty!|";
  30. }
  31. const auto& currentTask = taskQueue.front();
  32. return TaskString(currentTask);
  33. }
  34. } // namespace Internal
  35. void ApplePickerComponent::StartAutomatedOperation()
  36. {
  37. if (!m_currentAppleTasks.empty())
  38. {
  39. AZ_Error("ApplePicker", false, "Tasks still in progress for current picking!");
  40. return;
  41. }
  42. // Get effector reach
  43. AZ::Obb effectorRangeGlobalBox;
  44. ApplePickingRequestBus::EventResult(
  45. effectorRangeGlobalBox, m_effectorEntityId, &ApplePickingRequests::GetEffectorReachArea);
  46. // Find out apples within the reach
  47. QueryEnvironmentForAllApplesInBox(effectorRangeGlobalBox);
  48. // Tell effector to prepare for picking
  49. ApplePickingRequestBus::Event(m_effectorEntityId, &ApplePickingRequests::PrepareForPicking);
  50. }
  51. void ApplePickerComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
  52. {
  53. // TODO handle timeouts and incoming commands
  54. // TODO - a debug loop
  55. if (m_currentAppleTasks.empty())
  56. {
  57. StartAutomatedOperation();
  58. }
  59. }
  60. float ApplePickerComponent::ReportProgress()
  61. {
  62. // TODO (minor) - take into consideration current task progress (effector state)
  63. if (m_initialTasksSize == 0)
  64. {
  65. AZ_Warning("ApplePicker", false, "ReportProgress reporting 1 since no apples were found in the call");
  66. return 1.0f;
  67. }
  68. return 1.0f - (m_currentAppleTasks.size() / m_initialTasksSize);
  69. }
  70. void ApplePickerComponent::Activate()
  71. {
  72. m_effectorEntityId = GetEntityId(); // TODO - remove this once we expose this field
  73. ApplePickingNotificationBus::Handler::BusConnect();
  74. AZ::TickBus::Handler::BusConnect();
  75. }
  76. void ApplePickerComponent::Deactivate()
  77. {
  78. AZ::TickBus::Handler::BusDisconnect();
  79. ApplePickingNotificationBus::Handler::BusDisconnect();
  80. }
  81. void ApplePickerComponent::Reflect(AZ::ReflectContext* context)
  82. {
  83. if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
  84. {
  85. serialize->Class<ApplePickerComponent, AZ::Component>()->Version(1);
  86. if (AZ::EditContext* ec = serialize->GetEditContext())
  87. {
  88. ec->Class<ApplePickerComponent>("Apple picking component", "A demo component for apple picking")
  89. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  90. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
  91. ->Attribute(AZ::Edit::Attributes::Category, "AppleKraken");
  92. }
  93. }
  94. }
  95. void ApplePickerComponent::EffectorReadyForPicking()
  96. {
  97. PickNextApple();
  98. }
  99. void ApplePickerComponent::ApplePicked()
  100. {
  101. if (m_currentAppleTasks.empty())
  102. {
  103. AZ_Error("ApplePicker", false, "ApplePicked called but no current task");
  104. return;
  105. }
  106. AZ_TracePrintf("ApplePicker", "%s. Picked apple\n", Internal::CurrentTaskString(m_currentAppleTasks).c_str());
  107. }
  108. void ApplePickerComponent::AppleRetrieved()
  109. {
  110. if (m_currentAppleTasks.empty())
  111. {
  112. AZ_Error("ApplePicker", false, "AppleRetrieved called but no current task");
  113. return;
  114. }
  115. AZ_TracePrintf(
  116. "ApplePicker", "%s. An apple has been retrieved and stored\n", Internal::CurrentTaskString(m_currentAppleTasks).c_str());
  117. m_currentAppleTasks.pop();
  118. PickNextApple();
  119. }
  120. void ApplePickerComponent::PickingFailed(const AZStd::string& reason)
  121. { // TODO - refactor common code (debugs, checks)
  122. if (m_currentAppleTasks.empty())
  123. {
  124. AZ_Error("ApplePicker", false, "PickingFailed called but no current task");
  125. return;
  126. }
  127. AZ_TracePrintf(
  128. "ApplePicker", "%s. Picking failed due to: %s\n", Internal::CurrentTaskString(m_currentAppleTasks).c_str(), reason.c_str());
  129. m_currentAppleTasks.pop();
  130. PickNextApple();
  131. }
  132. void ApplePickerComponent::PickNextApple()
  133. {
  134. if (!m_currentAppleTasks.empty())
  135. { // Get another apple!
  136. ApplePickingRequestBus::Event(m_effectorEntityId, &ApplePickingRequests::PickApple, m_currentAppleTasks.front());
  137. return;
  138. }
  139. }
  140. void ApplePickerComponent::QueryEnvironmentForAllApplesInBox(const AZ::Obb& /*globalBox*/)
  141. {
  142. // TODO - query environment
  143. // Debug
  144. for (int i = 0; i < 5; ++i)
  145. {
  146. PickAppleTask emptyTask;
  147. m_currentAppleTasks.push(emptyTask);
  148. }
  149. }
  150. } // namespace AppleKraken