| 1 | #include "Library/Area/AreaObjDirector.h" |
| 2 | |
| 3 | #include "Library/Area/AreaInitInfo.h" |
| 4 | #include "Library/Area/AreaObj.h" |
| 5 | #include "Library/Area/AreaObjFactory.h" |
| 6 | #include "Library/Area/AreaObjGroup.h" |
| 7 | #include "Library/Area/AreaObjMtxConnecter.h" |
| 8 | #include "Library/Placement/PlacementFunction.h" |
| 9 | #include "Library/Placement/PlacementInfo.h" |
| 10 | |
| 11 | namespace al { |
| 12 | |
| 13 | AreaObjDirector::AreaObjDirector() = default; |
| 14 | |
| 15 | void AreaObjDirector::init(const AreaObjFactory* factory) { |
| 16 | mFactory = factory; |
| 17 | mMtxConnecterHolder = new AreaObjMtxConnecterHolder(0x100); |
| 18 | s32 nFactoryEntries = mFactory->getNumFactoryEntries(); |
| 19 | mAreaGroups = new AreaObjGroup*[nFactoryEntries]; |
| 20 | |
| 21 | for (s32 i = 0; i < nFactoryEntries; i++) |
| 22 | mAreaGroups[i] = nullptr; |
| 23 | } |
| 24 | |
| 25 | void AreaObjDirector::endInit() {} |
| 26 | |
| 27 | void AreaObjDirector::update() { |
| 28 | if (mMtxConnecterHolder) |
| 29 | mMtxConnecterHolder->update(); |
| 30 | } |
| 31 | |
| 32 | void AreaObjDirector::placement(const AreaInitInfo& initInfo) { |
| 33 | createAreaObjGroup(initInfo); |
| 34 | createAreaObjGroupBuffer(); |
| 35 | placementAreaObj(initInfo); |
| 36 | } |
| 37 | |
| 38 | void AreaObjDirector::placement(const AreaInitInfo* initInfoArray, s32 initInfoCount) { |
| 39 | for (s32 i = 0; i < initInfoCount; i++) |
| 40 | createAreaObjGroup(initInfo: initInfoArray[i]); |
| 41 | |
| 42 | createAreaObjGroupBuffer(); |
| 43 | |
| 44 | for (s32 i = 0; i < initInfoCount; i++) |
| 45 | placementAreaObj(initInfo: initInfoArray[i]); |
| 46 | } |
| 47 | |
| 48 | void AreaObjDirector::createAreaObjGroup(const AreaInitInfo& initInfo) { |
| 49 | PlacementInfo placementInfo(initInfo); |
| 50 | |
| 51 | s32 pInfoCount = getCountPlacementInfo(placementInfo); |
| 52 | for (s32 i = 0; i < pInfoCount; i++) { |
| 53 | PlacementInfo placementInfo2; |
| 54 | tryGetPlacementInfoByIndex(outPlacementInfo: &placementInfo2, placementInfo, index: i); |
| 55 | const char* pInfoName = nullptr; |
| 56 | tryGetObjectName(name: &pInfoName, placementInfo: placementInfo2); |
| 57 | |
| 58 | AreaCreatorFunction creatorFunc = nullptr; |
| 59 | s32 entryIndex = mFactory->getEntryIndex(creationPtr: &creatorFunc, entryName: pInfoName); |
| 60 | |
| 61 | if (!creatorFunc) |
| 62 | continue; |
| 63 | if (!mAreaGroups[entryIndex]) { |
| 64 | s32 size = mFactory->tryFindAddBufferSize(bufferName: pInfoName); |
| 65 | mAreaGroups[entryIndex] = new AreaObjGroup(pInfoName, size); |
| 66 | } |
| 67 | |
| 68 | mAreaGroups[entryIndex]->incrementCount(); |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | void AreaObjDirector::createAreaObjGroupBuffer() { |
| 73 | for (s32 i = 0; i < mFactory->getAreaGroupCount(); i++) { |
| 74 | const AreaGroupInfo& addBuffer = mFactory->getAreaGroupInfo()[i]; |
| 75 | AreaCreatorFunction creatorFunc = nullptr; |
| 76 | s32 entryIndex = mFactory->getEntryIndex(creationPtr: &creatorFunc, entryName: addBuffer.name); |
| 77 | if (!mAreaGroups[entryIndex]) |
| 78 | mAreaGroups[entryIndex] = new AreaObjGroup(addBuffer.name, addBuffer.size); |
| 79 | } |
| 80 | |
| 81 | s32 areaGroupCount = 0; |
| 82 | s32 nEntries = mFactory->getNumFactoryEntries(); |
| 83 | for (s32 i = 0; i < nEntries; i++) { |
| 84 | if (mAreaGroups[i] == nullptr) |
| 85 | continue; |
| 86 | mAreaGroups[i]->createBuffer(); |
| 87 | areaGroupCount++; |
| 88 | |
| 89 | for (s32 areaGroupIndex = i; areaGroupIndex > 0; areaGroupIndex--) { |
| 90 | AreaObjGroup* prevAreaObjGroup = mAreaGroups[areaGroupIndex - 1]; |
| 91 | if (prevAreaObjGroup) { |
| 92 | if (strcmp(mAreaGroups[areaGroupIndex]->getName(), prevAreaObjGroup->getName()) > |
| 93 | -1) |
| 94 | break; |
| 95 | } |
| 96 | mAreaGroups[areaGroupIndex - 1] = mAreaGroups[areaGroupIndex]; |
| 97 | mAreaGroups[areaGroupIndex] = prevAreaObjGroup; |
| 98 | } |
| 99 | } |
| 100 | mAreaGroupCount = areaGroupCount; |
| 101 | } |
| 102 | |
| 103 | void AreaObjDirector::placementAreaObj(const AreaInitInfo& initInfo) { |
| 104 | PlacementInfo pInfo(initInfo); |
| 105 | s32 pInfoCount = getCountPlacementInfo(placementInfo: pInfo); |
| 106 | for (s32 j = 0; j < pInfoCount; j++) { |
| 107 | PlacementInfo pInfo2; |
| 108 | tryGetPlacementInfoByIndex(outPlacementInfo: &pInfo2, placementInfo: pInfo, index: j); |
| 109 | const char* pInfoName = nullptr; |
| 110 | tryGetObjectName(name: &pInfoName, placementInfo: pInfo2); |
| 111 | |
| 112 | AreaCreatorFunction creatorFunc = nullptr; |
| 113 | mFactory->getEntryIndex(creationPtr: &creatorFunc, entryName: pInfoName); |
| 114 | if (creatorFunc == nullptr) |
| 115 | continue; |
| 116 | |
| 117 | const char* displayName; |
| 118 | getDisplayName(name: &displayName, placementInfo: pInfo2); |
| 119 | AreaObj* areaObj = creatorFunc(displayName); |
| 120 | AreaInitInfo initInfo2(pInfo2, initInfo); |
| 121 | areaObj->init(info: initInfo2); |
| 122 | |
| 123 | AreaObjGroup* areaGroup = getAreaObjGroup(name: pInfoName); |
| 124 | |
| 125 | areaGroup->registerAreaObj(newAreaObj: areaObj); |
| 126 | mMtxConnecterHolder->tryAddArea(areaObj, placementInfo: pInfo2); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | AreaObjGroup* AreaObjDirector::getAreaObjGroup(const char* name) const { |
| 131 | s32 lower = 0; |
| 132 | s32 upper = mAreaGroupCount; |
| 133 | while (lower < upper) { |
| 134 | s32 i = (lower + upper) / 2; |
| 135 | s32 equalString = strcmp(name, mAreaGroups[i]->getName()); |
| 136 | if (equalString == 0) |
| 137 | return mAreaGroups[i]; |
| 138 | else if (equalString > 0) |
| 139 | lower = i + 1; |
| 140 | else |
| 141 | upper = i; |
| 142 | } |
| 143 | return nullptr; |
| 144 | } |
| 145 | |
| 146 | bool AreaObjDirector::isExistAreaGroup(const char* name) const { |
| 147 | return getAreaObjGroup(name) != nullptr; |
| 148 | } |
| 149 | |
| 150 | AreaObj* AreaObjDirector::getInVolumeAreaObj(const char* name, const sead::Vector3f& position) { |
| 151 | AreaObjGroup* areaGroup = getAreaObjGroup(name); |
| 152 | if (!areaGroup) |
| 153 | return nullptr; |
| 154 | return areaGroup->getInVolumeAreaObj(position); |
| 155 | } |
| 156 | |
| 157 | AreaObjMtxConnecterHolder* AreaObjDirector::getMtxConnecterHolder() const { |
| 158 | return mMtxConnecterHolder; |
| 159 | } |
| 160 | |
| 161 | } // namespace al |
| 162 | |