Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions engine/includes/components/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ class ENGINE_EXPORT Actor : public Object {

bool m_static;

bool m_muteUpdates;

};

#endif // ACTOR_H
2 changes: 1 addition & 1 deletion engine/includes/editor/converters/prefabconverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class PrefabConverter : public AssetConverter {

protected:
Variant readJson(const std::string &data, AssetConverterSettings *);
void injectResource(Variant &origin, Resource *resource);
void injectResource(Object *data, Resource *resource);

virtual Resource *requestResource();

Expand Down
1 change: 0 additions & 1 deletion engine/includes/resources/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class ENGINE_EXPORT Map : public Resource {

public:
Map();
~Map();

Scene *scene() const;
void setScene(Scene *scene);
Expand Down
7 changes: 4 additions & 3 deletions engine/includes/resources/prefab.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class ENGINE_EXPORT Prefab : public Resource {

public:
Prefab();
~Prefab();

Actor *actor() const;
void setActor(Actor *actor);
Expand All @@ -28,11 +27,13 @@ class ENGINE_EXPORT Prefab : public Resource {
ObjectList absentInCloned(const ConstObjectList &cloned);

private:
void makeCache(Object *object);

void switchState(State state) override;

void loadUserData(const VariantMap &data) override;
VariantMap saveUserData() const override;

void makeCache(Object *object);

private:
friend class ActorTest;

Expand Down
118 changes: 70 additions & 48 deletions engine/src/components/actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ Actor::Actor() :
m_layers(CommandBuffer::DEFAULT | CommandBuffer::RAYCAST | CommandBuffer::SHADOWCAST | CommandBuffer::TRANSLUCENT),
m_flags(Actor::ENABLE | Actor::SELECTABLE),
m_hierarchyEnable(m_flags & Actor::ENABLE),
m_static(false) {
m_static(false),
m_muteUpdates(false) {

}

Expand Down Expand Up @@ -390,18 +391,34 @@ void Actor::setPrefab(Prefab *prefab) {
if(m_prefab != prefab) {
if(m_prefab) {
m_prefab->unsubscribe(this);
m_prefab->decRef();
}

m_prefab = prefab;
if(m_prefab) {
m_prefab->incRef();
m_muteUpdates = true;
m_prefab->subscribe(&Actor::prefabUpdated, this);
m_muteUpdates = false;
} else {
clearCloneRef();
}
}
}

Object *findByClone(uint32_t uuid, Object *root) {
if(root) {
if(root->clonedFrom() == uuid) {
return root;
}
for(auto &it : root->getChildren()) {
Object *result = findByClone(uuid, it);
if(result) {
return result;
}
}
}
return nullptr;
}

/*!
\internal
*/
Expand All @@ -419,7 +436,9 @@ void Actor::loadObjectData(const VariantMap &data) {
if(it != data.end()) {
for(auto &item : (*it).second.toList()) {
uint32_t uuid = static_cast<uint32_t>(item.toInt());
Object *result = ObjectSystem::findObject(uuid, actor);

// Need to do dearch by cloneID!
Object *result = findByClone(uuid, actor);
if(result && result != actor) {
delete result;
}
Expand All @@ -439,7 +458,8 @@ void Actor::loadObjectData(const VariantMap &data) {
VariantList array = item.toList();

uint32_t originID = static_cast<uint32_t>(array.front().toInt());
Object *result = ObjectSystem::findObject(originID, this);
// Need to do dearch by cloneID!
Object *result = findByClone(originID, this);
if(result) {
uint32_t newID = static_cast<uint32_t>(array.back().toInt());
ObjectSystem::replaceUUID(result, newID);
Expand All @@ -462,51 +482,49 @@ void Actor::loadUserData(const VariantMap &data) {
m_flags = it->second.toInt();
}

if(m_prefab) {
it = data.find(gData);
if(it != data.end()) {
Object::ObjectList objects;
Object::enumObjects(this, objects);

std::unordered_map<uint32_t, Object *> cacheMap;
for(auto &object : objects) {
uint32_t clone = object->clonedFrom();
cacheMap[clone] = object;
}
it = data.find(gData);
if(it != data.end()) {
Object::ObjectList objects;
Object::enumObjects(this, objects);

const VariantList &list = (*it).second.toList();
for(auto &item : list) {
const VariantList &fields = item.toList();

uint32_t cloned = static_cast<uint32_t>(fields.front().toInt());
auto object = cacheMap.find(cloned);
if(object != cacheMap.end()) {
const MetaObject *meta = (*object).second->metaObject();
for(auto &property : fields.back().toMap()) {
int32_t index = meta->indexOfProperty(property.first.c_str());
if(index > -1) {
MetaProperty prop = meta->property(index);
bool isObject = prop.type().flags() & MetaType::BASE_OBJECT;
Variant var(property.second);
if(var.type() == MetaType::VARIANTLIST) {
VariantList resultList;
for(auto it : var.toList()) {
Variant result(Actor::loadObject(it));
if(!isObject) {
isObject = result.isValid();
}
resultList.push_back(result);
}
if(isObject) {
var = resultList;
}
} else {
if(isObject) {
var = loadObject(var);
ObjectSystem::ObjectMap cacheMap;
for(auto &object : objects) {
uint32_t clone = object->clonedFrom();
cacheMap[clone] = object;
}

const VariantList &list = (*it).second.toList();
for(auto &item : list) {
const VariantList &fields = item.toList();

uint32_t cloned = static_cast<uint32_t>(fields.front().toInt());
auto object = cacheMap.find(cloned);
if(object != cacheMap.end()) {
const MetaObject *meta = (*object).second->metaObject();
for(auto &property : fields.back().toMap()) {
int32_t index = meta->indexOfProperty(property.first.c_str());
if(index > -1) {
MetaProperty prop = meta->property(index);
bool isObject = prop.type().flags() & MetaType::BASE_OBJECT;
Variant var(property.second);
if(var.type() == MetaType::VARIANTLIST) {
VariantList resultList;
for(auto it : var.toList()) {
Variant result(Actor::loadObject(it));
if(!isObject) {
isObject = result.isValid();
}
resultList.push_back(result);
}
if(isObject) {
var = resultList;
}
} else {
if(isObject) {
var = loadObject(var);
}
prop.write((*object).second, var);
}
prop.write((*object).second, var);
}
}
}
Expand All @@ -526,9 +544,9 @@ Variant Actor::loadObject(Variant &value) {
} else if(value.type() == MetaType::INTEGER) { // Component
uint32_t uuid = static_cast<uint32_t>(value.toInt());

Object *obj = Engine::findObject(uuid, this);
Object *obj = Engine::findObject(uuid);
if(obj == nullptr) {
obj = Engine::findObject(uuid, Engine::findRoot(this));
obj = Engine::findObject(uuid);
}
if(obj) {
const char *name = obj->metaObject()->name();
Expand Down Expand Up @@ -663,6 +681,10 @@ Variant Actor::saveObject(const Variant &lv, const Variant &rv) const {
void Actor::prefabUpdated(int state, void *ptr) {
Actor *p = static_cast<Actor *>(ptr);

if(p->m_muteUpdates) {
return;
}

switch(state) {
case Resource::Loading: {
p->m_data = p->saveUserData();
Expand Down
2 changes: 1 addition & 1 deletion engine/src/components/component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ Object *loadObjectHelper(const Variant &value, const MetaObject *meta, Object *r
} else {
uint32_t uuid = value.toInt();
if(uuid) {
object = Engine::findObject(uuid, root);
object = Engine::findObject(uuid);
}
}

Expand Down
2 changes: 1 addition & 1 deletion engine/src/editor/assetmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ void AssetManager::makePrefab(const QString &source, const QFileInfo &target) {
int index = source.indexOf(':');
QString id = source.left(index);
QString name = source.mid(index + 1);
Actor *actor = dynamic_cast<Actor *>(Engine::findObject(id.toUInt(), Engine::world()));
Actor *actor = dynamic_cast<Actor *>(Engine::findObject(id.toUInt()));
if(actor) {
Actor *clone = static_cast<Actor *>(actor->clone(actor->parent()));
QString path = m_projectManager->contentPath() + "/" + target.filePath() + "/" + name + ".fab";
Expand Down
55 changes: 23 additions & 32 deletions engine/src/editor/converters/prefabconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,33 @@ Actor *PrefabConverter::createActor(const AssetConverterSettings *settings, cons
AssetConverter::ReturnCode PrefabConverter::convertFile(AssetConverterSettings *settings) {
PROFILE_FUNCTION();

AssetConverter::ReturnCode result = InternalError;

QFile src(settings->source());
if(src.open(QIODevice::ReadOnly)) {
std::string data = src.readAll().toStdString();
src.close();

Variant actor = readJson(data, settings);
injectResource(actor, requestResource());
Resource *resource = requestResource();

Variant variant = readJson(data, settings);
Object *object = Engine::toObject(variant);
if(object) {
injectResource(object, resource);

QFile file(settings->absoluteDestination());
if(file.open(QIODevice::WriteOnly)) {
ByteArray data = Bson::save(actor);
file.write(reinterpret_cast<const char *>(data.data()), data.size());
file.close();
QFile file(settings->absoluteDestination());
if(file.open(QIODevice::WriteOnly)) {
ByteArray data = Bson::save(Engine::toVariant(resource));
file.write(reinterpret_cast<const char *>(data.data()), data.size());
file.close();

return Success;
result = Success;
}
}

delete resource;
}
return InternalError;
return result;
}

Variant PrefabConverter::readJson(const std::string &data, AssetConverterSettings *settings) {
Expand Down Expand Up @@ -96,33 +105,15 @@ Variant PrefabConverter::readJson(const std::string &data, AssetConverterSetting
return result;
}

void PrefabConverter::injectResource(Variant &origin, Resource *resource) {
void PrefabConverter::injectResource(Object *data, Resource *resource) {
PROFILE_FUNCTION();

VariantList &objects = *(reinterpret_cast<VariantList *>(origin.data()));
VariantList &o = *(reinterpret_cast<VariantList *>(objects.front().data()));

auto i = o.begin(); // type
i++; // uuid
i++; // parent
*i = resource->uuid();
data->setParent(resource);

objects.push_front(Engine::toVariant(resource).toList().front());

QSet<QString> modules;
for(auto &it : objects) {
VariantList *object = reinterpret_cast<VariantList *>(it.data());
if(object) {
QString type = QString::fromStdString(object->begin()->toString());
QString module = PluginManager::instance()->getModuleName(type);
if(!module.isEmpty() && module != (QString("Module") + ProjectSettings::instance()->projectName())) {
modules.insert(module);
}
}
Prefab *prefab = dynamic_cast<Prefab *>(resource);
if(prefab) {
prefab->setActor(dynamic_cast<Actor *>(data));
}
ProjectSettings::instance()->reportModules(modules);

Engine::unloadResource(resource);
}

Resource *PrefabConverter::requestResource() {
Expand Down
3 changes: 0 additions & 3 deletions engine/src/resources/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ Map::Map() :

}

Map::~Map() {
delete m_scene;
}
/*!
Returns a scene which can be added to the scene graph.
*/
Expand Down
Loading