예제 #1
0
Profile* ProfileManager::CreateProfileObject(const char* user,
                                             ProfileType device,
                                             const char** device_name)
{
    Lock::Locker lockScope(&ProfileLock);

    Profile* profile = NULL;
    switch (device)
    {
        case Profile_GenericHMD:
            *device_name = NULL;
            profile = new HMDProfile(Profile_GenericHMD, user);
            break;
        case Profile_RiftDK1:
            *device_name = "RiftDK1";
            profile = new RiftDK1Profile(user);
            break;
        case Profile_RiftDKHD:
            *device_name = "RiftDKHD";
            profile = new RiftDKHDProfile(user);
            break;
        case Profile_Unknown:
            break;
    }

    return profile;
}
void MessageHandlerRef::SetHandler(MessageHandler* handler)
{    
    OVR_ASSERT(!handler ||
               MessageHandlerImpl::FromHandler(handler)->pLock == pLock);    
    Lock::Locker lockScope(pLock);
    SetHandler_NTS(handler);
}
예제 #3
0
bool DeviceHandle::enumerateNext(const DeviceEnumerationArgs& args)
{
    if (GetType() == Device_None)
        return false;
    
    Ptr<DeviceManagerImpl> managerKeepAlive;
    Lock::Locker           lockScope(pImpl->GetLock());
    
    DeviceCreateDesc* next = pImpl;
    // If manager was destroyed, we get removed from the list.
    if (!pImpl->pNext)
        return false;

    managerKeepAlive = next->GetManagerImpl();
    OVR_ASSERT(managerKeepAlive);
    
    do {
        next = next->pNext;

        if (managerKeepAlive->Devices.IsNull(next))
        {
            pImpl->Release();
            pImpl = 0;
            return false;
        }

    } while(!args.MatchRule(next->Type, next->Enumerated));

    next->AddRef();
    pImpl->Release();
    pImpl = next;

    return true;
}
예제 #4
0
// Clear the local profile cache
void ProfileManager::ClearProfileData()
{
    Lock::Locker lockScope(&ProfileLock);

    ProfileCache.Clear();
    Changed = false;
}
예제 #5
0
// Removes an existing profile.  Returns true if the profile was found and deleted
// and returns false otherwise.
bool ProfileManager::Delete(const Profile* profile)
{
    Lock::Locker lockScope(&ProfileLock);

    if (OVR_strcmp(profile->Name, "default") == 0)
        return false;  // don't delete a default profile

    if (CacheDevice == Profile_Unknown)
        LoadCache(profile->Type);

    // Look for the existence of this profile
    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        if (OVR_strcmp(profile->Name, ProfileCache[i]->Name) == 0)
        {  
            if (OVR_strcmp(profile->Name, DefaultProfile) == 0)
                DefaultProfile.Clear();
            
            ProfileCache.RemoveAt(i);
            Changed = true;
            return true;
        }
    }

    return false;
}
예제 #6
0
// Returns the user id of a specific user in the list.  The returned 
// memory is locally allocated and should not be stored or deleted.  Returns NULL
// if the index is invalid
const char* ProfileManager::GetUser(unsigned int index)
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(false);
        if (ProfileCache == NULL)
            return NULL;
    }

    JSON* users = ProfileCache->GetItemByName("Users");
    
    if (users && index < users->GetItemCount())
    {
        JSON* user_item = users->GetItemByIndex(index);
        if (user_item)
        {
            JSON* user = user_item->GetFirstItem();
            if (user)
            {
                JSON* userid = user_item->GetItemByName(OVR_KEY_USER);
                if (userid)
                    return userid->Value.ToCStr();
            }
        }
    }
    

    return NULL;
}
예제 #7
0
// Clear the local profile cache
void ProfileManager::ClearCache()
{
    Lock::Locker lockScope(&ProfileLock);

    ProfileCache.Clear();
    CacheDevice = Profile_Unknown;
}
예제 #8
0
bool ProfileManager::CreateUser(const char* user, const char* name)
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(true);
        if (ProfileCache == NULL)
            return false;
    }

    JSON* users = ProfileCache->GetItemByName("Users");
    if (users == NULL)
    {   // Generate the User section
        users = JSON::CreateArray();
        ProfileCache->AddItem("Users", users);
//TODO: Insert this before the TaggedData
    }

    // Search for the pre-existence of this user
    JSON* user_item = users->GetFirstItem();
    int index = 0;
    while (user_item)
    {
        JSON* userid = user_item->GetItemByName("User");
        int compare = OVR_strcmp(user, userid->Value);
        if (compare == 0)
        {   // The user already exists so simply update the fields
            JSON* name_item = user_item->GetItemByName("Name");
            if (name_item && OVR_strcmp(name, name_item->Value) != 0)
            {
                name_item->Value = name;
                Changed = true;
            }
            return true;
        }
        else if (compare < 0)
        {   // A new user should be placed before this item
            break;
        }
        
        user_item = users->GetNextItem(user_item);
        index++;
    }

    // Create and fill the user struct
    JSON* new_user = JSON::CreateObject();
    new_user->AddStringItem(OVR_KEY_USER, user);
    new_user->AddStringItem(OVR_KEY_NAME, name);
    // user_item->AddStringItem("Password", password);

    if (user_item == NULL)
        users->AddArrayElement(new_user);
    else
        users->InsertArrayElement(index, new_user);

    Changed = true;
    return true;
}
예제 #9
0
// Serializes the profiles to disk.
void ProfileManager::SaveCache()
{
    String path = GetProfilePath(true);
 
    Lock::Locker lockScope(&ProfileLock);

    // TODO: Since there is only a single device type now, a full tree overwrite
    // is sufficient but in the future a selective device branch replacement will
    // be necessary

    Ptr<JSON> root = *JSON::CreateObject();
    root->AddNumberItem("Oculus Profile Version", PROFILE_VERSION);
    root->AddStringItem("CurrentProfile", DefaultProfile);
    root->AddNumberItem("ProfileCount", (double) ProfileCache.GetSize());

    // Generate a JSON subtree for each profile
    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        Profile* profile = ProfileCache[i];

        JSON* json_profile = JSON::CreateObject();
        json_profile->Name = "Profile";
        json_profile->AddStringItem("Name", profile->Name);
        const char* gender;
        switch (profile->GetGender())
        {
            case Profile::Gender_Male:   gender = "Male"; break;
            case Profile::Gender_Female: gender = "Female"; break;
            default: gender = "Unspecified";
        }
        json_profile->AddStringItem("Gender", gender);
        json_profile->AddNumberItem("PlayerHeight", profile->PlayerHeight);
        json_profile->AddNumberItem("IPD", profile->IPD);

        if (profile->Type == Profile_RiftDK1)
        {
            RiftDK1Profile* riftdk1 = (RiftDK1Profile*)profile;
            JSON* json_riftdk1 = JSON::CreateObject();
            json_profile->AddItem("RiftDK1", json_riftdk1);

            const char* eyecup = "A";
            switch (riftdk1->EyeCups)
            {
                case RiftDK1Profile::EyeCup_A: eyecup = "A"; break;
                case RiftDK1Profile::EyeCup_B: eyecup = "B"; break;
                case RiftDK1Profile::EyeCup_C: eyecup = "C"; break;
            }
            json_riftdk1->AddStringItem("EyeCup", eyecup);
            json_riftdk1->AddNumberItem("LL", riftdk1->LL);
            json_riftdk1->AddNumberItem("LR", riftdk1->LR);
            json_riftdk1->AddNumberItem("RL", riftdk1->RL);
            json_riftdk1->AddNumberItem("RR", riftdk1->RR);
        }

        root->AddItem("Profile", json_profile);
    }

    root->Save(path);
}
예제 #10
0
// Returns the number of stored profiles for this device type
int ProfileManager::GetProfileCount(ProfileType device)
{
    Lock::Locker lockScope(&ProfileLock);

    if (CacheDevice == Profile_Unknown)
        LoadCache(device);

    return (int)ProfileCache.GetSize();
}
예제 #11
0
    // Resets the current orientation
void SensorFusion::Reset()
{
    Lock::Locker lockScope(Handler.GetHandlerLock());
    Q                     = Quatf();
    QUncorrected          = Quatf();
    Stage                 = 0;
    RunningTime           = 0;
    MagNumReferences      = 0;
    MagRefIdx             = -1;
    GyroOffset            = Vector3f();
}
예제 #12
0
// Serializes the profiles to disk.
void ProfileManager::Save()
{
	Lock::Locker lockScope(&ProfileLock);

	if (ProfileCache == NULL)
		return;

    // Save the profile to disk
    BasePath = GetBaseOVRPath(true);  // create the base directory if it doesn't exist
    String path = GetProfilePath();
    ProfileCache->Save(path);
    Changed = false;
}
MessageHandlerRef::~MessageHandlerRef()
{
    {
        Lock::Locker lockScope(pLock);
        if (pHandler)
        {
            pHandler = 0;
            RemoveNode();
        }
    }
    MessageHandlerSharedLock.ReleaseLock(pLock);
    pLock = 0;
}
예제 #14
0
bool ProfileManager::HasProfile(ProfileType device, const char* name)
{
    Lock::Locker lockScope(&ProfileLock);

    if (CacheDevice == Profile_Unknown)
        LoadCache(device);

    for (unsigned i = 0; i< ProfileCache.GetSize(); i++)
    {
        if (ProfileCache[i] && OVR_strcmp(ProfileCache[i]->Name, name) == 0)
            return true;
    }
    return false;
}
예제 #15
0
// Returns a specific profile object in the list.  The returned memory should be
// encapsulated in a Ptr<> object or released after use.  Returns NULL if the index
// is invalid
Profile* ProfileManager::LoadProfile(ProfileType device, unsigned int index)
{
    Lock::Locker lockScope(&ProfileLock);

    if (CacheDevice == Profile_Unknown)
        LoadCache(device);

    if (index < ProfileCache.GetSize())
    {
        Profile* profile = ProfileCache[index];
        return profile->Clone();
    }
    else
    {
        return NULL;
    }
}
예제 #16
0
// Returns the name of the profile that is marked as the current default user.
const char* ProfileManager::GetDefaultProfileName(ProfileType device)
{
    Lock::Locker lockScope(&ProfileLock);

    if (CacheDevice == Profile_Unknown)
        LoadCache(device);

    if (ProfileCache.GetSize() > 0)
    {
        OVR_strcpy(NameBuff, Profile::MaxNameLen, DefaultProfile);
        return NameBuff;
    }
    else
    {
        return NULL;
    }
}
예제 #17
0
// Returns the number of stored profiles for this device type
int ProfileManager::GetUserCount()
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(false);
        if (ProfileCache == NULL)
            return 0;
    }

    JSON* users = ProfileCache->GetItemByName("Users");
    if (users == NULL)
        return 0;

    return users->GetItemCount();
}
예제 #18
0
// Marks a particular user as the current default user.
bool ProfileManager::SetDefaultProfileName(ProfileType device, const char* name)
{
    Lock::Locker lockScope(&ProfileLock);

    if (CacheDevice == Profile_Unknown)
        LoadCache(device);
// TODO: I should verify that the user is valid
    if (ProfileCache.GetSize() > 0)
    {
        DefaultProfile = name;
        Changed = true;
        return true;
    }
    else
    {
        return false;
    }
}
예제 #19
0
// Returns the profile name of a specific profile in the list.  The returned 
// memory is locally allocated and should not be stored or deleted.  Returns NULL
// if the index is invalid
const char* ProfileManager::GetProfileName(ProfileType device, unsigned int index)
{
    Lock::Locker lockScope(&ProfileLock);

    if (CacheDevice == Profile_Unknown)
        LoadCache(device);

    if (index < ProfileCache.GetSize())
    {
        Profile* profile = ProfileCache[index];
        OVR_strcpy(NameBuff, Profile::MaxNameLen, profile->Name);
        return NameBuff;
    }
    else
    {
        return NULL;
    }
}
예제 #20
0
bool ProfileManager::RemoveUser(const char* user)
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(false);
        if (ProfileCache == NULL)
            return true;
    }

    JSON* users = ProfileCache->GetItemByName("Users");
    if (users == NULL)
        return true;

    // Remove this user from the User table
    JSON* user_item = users->GetFirstItem();
    while (user_item)
    {
        JSON* userid = user_item->GetItemByName("User");
        if (OVR_strcmp(user, userid->Value) == 0)
        {   // Delete the user entry
            user_item->RemoveNode();
            user_item->Release();
            Changed = true;
            break;
        }
        
        user_item = users->GetNextItem(user_item);
    }

    // Now remove all data entries with this user tag
    JSON* tagged_data = ProfileCache->GetItemByName("TaggedData");
    Array<JSON*> user_items;
    FilterTaggedData(tagged_data, "User", user, user_items);
    for (unsigned int i=0; i<user_items.GetSize(); i++)
    {
        user_items[i]->RemoveNode();
        user_items[i]->Release();
        Changed = true;
    }
 
    return Changed;
}
        // This is a simple predictive filter based only on extrapolating the smoothed, current angular velocity.
        // Note that both QP (the predicted future orientation) and Q (the current orientation) are both maintained.
Quatf       SensorFusion::GetPredictedOrientation()
{		
	Lock::Locker lockScope(Handler.GetHandlerLock());
	Quatf qP = QUncorrected;
	if (EnablePrediction) {
#if 1
	    Vector3f angVelF  = FAngV.SavitzkyGolaySmooth8();
        float    angVelFL = angVelF.Length();
            
        if (angVelFL > 0.001f)
        {
            Vector3f    rotAxisP      = angVelF / angVelFL;  
            float       halfRotAngleP = angVelFL * PredictionDT * 0.5f;
            float       sinaHRAP      = sin(halfRotAngleP);
		    Quatf       deltaQP(rotAxisP.x*sinaHRAP, rotAxisP.y*sinaHRAP,
                                rotAxisP.z*sinaHRAP, cos(halfRotAngleP));
            qP = QUncorrected * deltaQP;
        }
#else
        Quatd qpd = Quatd(Q.x,Q.y,Q.z,Q.w);
        int predictionStages = (int)(PredictionDT / DeltaT);
        Vector3f  aa = FAngV.SavitzkyGolayDerivative12();
        Vector3d  aad     = Vector3d(aa.x,aa.y,aa.z);
        Vector3f angVelF  = FAngV.SavitzkyGolaySmooth8();
        Vector3d  avkd    = Vector3d(angVelF.x,angVelF.y,angVelF.z);
        for (int i = 0; i < predictionStages; i++)
        {
            double angVelLengthd = avkd.Length();
            Vector3d rotAxisd      = avkd / angVelLengthd;
            double halfRotAngled = angVelLengthd * DeltaT * 0.5;
            double sinHRAd       = sin(halfRotAngled);
            Quatd  deltaQd       = Quatd(rotAxisd.x*sinHRAd, rotAxisd.y*sinHRAd, rotAxisd.z*sinHRAd,
                                         cos(halfRotAngled));
            qpd =  qpd * deltaQd;
            // Update vel
            avkd += aad;
        }
        qP = Quatf((float)qpd.x,(float)qpd.y,(float)qpd.z,(float)qpd.w);
#endif
	}
    return qP;
}    
예제 #22
0
// Saves a new or existing profile.  Returns true on success or false on an
// invalid or failed save.
bool ProfileManager::Save(const Profile* profile)
{
    Lock::Locker lockScope(&ProfileLock);

    if (OVR_strcmp(profile->Name, "default") == 0)
        return false;  // don't save a default profile

    // TODO: I should also verify that this profile type matches the current cache
    if (CacheDevice == Profile_Unknown)
        LoadCache(profile->Type);

    // Look for the pre-existence of this profile
    bool added = false;
    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        int compare = OVR_strcmp(profile->Name, ProfileCache[i]->Name);
              
        if (compare == 0)
        {   
            // TODO: I should do a proper field comparison to avoid unnecessary
            // overwrites and file saves

            // Replace the previous instance with the new profile
            ProfileCache[i] = *profile->Clone();
            added   = true;
            Changed = true;
            break;
        }
    }

    if (!added)
    {
        ProfileCache.PushBack(*profile->Clone());
        if (ProfileCache.GetSize() == 1)
            CacheDevice = profile->Type;

        Changed = true;
    }

    return true;
}
예제 #23
0
// Returns a profile object for a particular device and user name.  The returned 
// memory should be encapsulated in a Ptr<> object or released after use.  Returns 
// NULL if the profile is not found
Profile* ProfileManager::LoadProfile(ProfileType device, const char* user)
{
    if (user == NULL)
        return NULL;

    Lock::Locker lockScope(&ProfileLock);
    
    if (CacheDevice == Profile_Unknown)
        LoadCache(device);

    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        if (OVR_strcmp(user, ProfileCache[i]->Name) == 0)
        {   // Found the requested user profile
            Profile* profile = ProfileCache[i];
            return profile->Clone();
        }
    }

    return NULL;
}
예제 #24
0
//-----------------------------------------------------------------------------
Profile* ProfileManager::GetTaggedProfile(const char** tag_names, const char** tags, int num_tags)
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(false);
        if (ProfileCache == NULL)
            return NULL;
    }

    JSON* tagged_data = ProfileCache->GetItemByName("TaggedData");
    OVR_ASSERT(tagged_data);
    if (tagged_data == NULL)
        return NULL;
    
    Profile* profile = new Profile(BasePath);
    
    JSON* vals = FindTaggedData(tagged_data, tag_names, tags, num_tags);
    if (vals)
    {   
        JSON* item = vals->GetFirstItem();
        while (item)
        {
            //printf("Add %s, %s\n", item->Name.ToCStr(), item->Value.ToCStr());
            //profile->Settings.Set(item->Name, item->Value);
            profile->SetValue(item);
            item = vals->GetNextItem(item);
        }

        return profile;
    }
    else
    {
        profile->Release();
        return NULL;
    }
}
예제 #25
0
//  A predictive filter based on extrapolating the smoothed, current angular velocity
Quatf SensorFusion::GetPredictedOrientation(float pdt)
{		
    Lock::Locker lockScope(Handler.GetHandlerLock());
    Quatf        qP = Q;
    
    if (EnablePrediction)
    {
        // This method assumes a constant angular velocity
        Vector3f angVelF  = FAngV.SavitzkyGolaySmooth8();
        float    angVelFL = angVelF.Length();

        // Force back to raw measurement
        angVelF  = AngV;
        angVelFL = AngV.Length();

        // Dynamic prediction interval: Based on angular velocity to reduce vibration
        const float minPdt   = 0.001f;
        const float slopePdt = 0.1f;
        float       newpdt   = pdt;
        float       tpdt     = minPdt + slopePdt * angVelFL;
        if (tpdt < pdt)
            newpdt = tpdt;
        //LogText("PredictonDTs: %d\n",(int)(newpdt / PredictionTimeIncrement + 0.5f));

        if (angVelFL > 0.001f)
        {
            Vector3f    rotAxisP      = angVelF / angVelFL;  
            float       halfRotAngleP = angVelFL * newpdt * 0.5f;
            float       sinaHRAP      = sin(halfRotAngleP);
            Quatf       deltaQP(rotAxisP.x*sinaHRAP, rotAxisP.y*sinaHRAP,
                                rotAxisP.z*sinaHRAP, cos(halfRotAngleP));
            qP = Q * deltaQP;
        }
    }
    return qP;
}    
예제 #26
0
//-----------------------------------------------------------------------------
Profile* ProfileManager::GetProfile(const ProfileDeviceKey& deviceKey, const char* user)
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(false);
        if (ProfileCache == NULL)
            return NULL;
    }
    
	Profile* profile = new Profile(BasePath);

	if (deviceKey.Valid)
    {
		if (!profile->LoadDeviceProfile(deviceKey) && (user == NULL))
        {
            profile->Release();
            return NULL;
        }
    }
    
    if (user)
    {
		const char* product_str = deviceKey.ProductName.IsEmpty() ? NULL : deviceKey.ProductName.ToCStr();
		const char* serial_str = deviceKey.PrintedSerial.IsEmpty() ? NULL : deviceKey.PrintedSerial.ToCStr();

        if (!profile->LoadProfile(ProfileCache.GetPtr(), user, product_str, serial_str))
        {
            profile->Release();
            return NULL;
        }
    }

    return profile;
}
예제 #27
0
//-----------------------------------------------------------------------------
bool ProfileManager::SetTaggedProfile(const char** tag_names, const char** tags, int num_tags, Profile* profile)
{
    Lock::Locker lockScope(&ProfileLock);

    if (ProfileCache == NULL)
    {   // Load the cache
        LoadCache(true);
        if (ProfileCache == NULL)
            return false;  // TODO: Generate a new profile DB
    }

    JSON* tagged_data = ProfileCache->GetItemByName("TaggedData");
    OVR_ASSERT(tagged_data);
    if (tagged_data == NULL)
        return false;

    // Get the cached tagged data section
    JSON* vals = FindTaggedData(tagged_data, tag_names, tags, num_tags);
    if (vals == NULL)
    {  
        JSON* tagged_item = JSON::CreateObject();
        JSON* taglist = JSON::CreateArray();
        for (int i=0; i<num_tags; i++)
        {
            JSON* k = JSON::CreateObject();
            k->AddStringItem(tag_names[i], tags[i]);
            taglist->AddArrayElement(k);
        }

        vals = JSON::CreateObject();
        
        tagged_item->AddItem("tags", taglist);
        tagged_item->AddItem("vals", vals);
        tagged_data->AddArrayElement(tagged_item);
    }

    // Now add or update each profile setting in cache
    for (unsigned int i=0; i<profile->Values.GetSize(); i++)
    {
        JSON* value = profile->Values[i];
        
        bool found = false;
        JSON* item = vals->GetFirstItem();
        while (item)
        {
            if (value->Name == item->Name)
            {
                // Don't allow a pre-existing type to be overridden
                OVR_ASSERT(value->Type == item->Type);

                if (value->Type == item->Type)
                {   // Check for the same value
                    if (value->Type == JSON_Array)
                    {   // Update each array item
                        if (item->GetArraySize() == value->GetArraySize())
                        {   // Update each value (assumed to be basic types and not array of objects)
                            JSON* value_element = value->GetFirstItem();
                            JSON* item_element = item->GetFirstItem();
                            while (item_element && value_element)
                            {
                                if (value_element->Type == JSON_String)
                                {
                                    if (item_element->Value != value_element->Value)
                                    {   // Overwrite the changed value and mark for file update
                                        item_element->Value = value_element->Value;
                                        Changed = true;
                                    }
                                }
                                else {
                                    if (item_element->dValue != value_element->dValue)
                                    {   // Overwrite the changed value and mark for file update
                                        item_element->dValue = value_element->dValue;
                                        Changed = true;
                                    }
                                }
                                
                                value_element = value->GetNextItem(value_element);
                                item_element = item->GetNextItem(item_element);
                            }
                        }
                        else
                        {   // if the array size changed, simply create a new one                            
// TODO: Create the new array
                        }
                    }
                    else if (value->Type == JSON_String)
                    {
                        if (item->Value != value->Value)
                        {   // Overwrite the changed value and mark for file update
                            item->Value = value->Value;
                            Changed = true;
                        }
                    }
                    else {
                        if (item->dValue != value->dValue)
                        {   // Overwrite the changed value and mark for file update
                            item->dValue = value->dValue;
                            Changed = true;
                        }
                    }
                }
                else
                {
                    return false;
                }

                found = true;
                break;
            }
            
            item = vals->GetNextItem(item);
        }

        if (!found)
        {   // Add the new value
            Changed = true;

            if (value->Type == JSON_String)
                vals->AddStringItem(value->Name, value->Value);
            else if (value->Type == JSON_Bool)
                vals->AddBoolItem(value->Name, ((int)value->dValue != 0));
            else if (value->Type == JSON_Number)
                vals->AddNumberItem(value->Name, value->dValue);
            else if (value->Type == JSON_Array)
                vals->AddItem(value->Name, value->Copy());
            else
            {
                OVR_ASSERT(false);
                Changed = false;
            }
        }
    }

    return true;
}
예제 #28
0
// Populates the local profile cache.  This occurs on the first access of the profile
// data.  All profile operations are performed against the local cache until the
// ProfileManager is released or goes out of scope at which time the cache is serialized
// to disk.
void ProfileManager::LoadCache(bool create)
{
    Lock::Locker lockScope(&ProfileLock);

    ClearProfileData();

    String path = GetProfilePath();

    Ptr<JSON> root = *JSON::Load(path);
    if (root == NULL)
    {   
        path = BasePath + "/Profiles.json";  // look for legacy profile
        root = *JSON::Load(path);
        
        if (root == NULL)
        {
            if (create)
            {   // Generate a skeleton profile database
                root = *JSON::CreateObject();
                root->AddNumberItem("Oculus Profile Version", 2.0);
                root->AddItem("Users", JSON::CreateArray());
                root->AddItem("TaggedData", JSON::CreateArray());
                ProfileCache = root;
            }
            
            return;
        }

        // Verify the legacy version
        JSON* version_item = root->GetFirstItem();
        if (version_item->Name == "Oculus Profile Version")
        {
            int major = atoi(version_item->Value.ToCStr());
            if (major != 1)
                return;   // don't use the file on unsupported major version number
        }
        else
        {
            return;      // invalid file
        }

        // Convert the legacy format to the new database format
        LoadV1Profiles(root);
    }
    else
    {
        // Verify the file format and version
        JSON* version_item = root->GetFirstItem();
        if (version_item->Name == "Oculus Profile Version")
        {
            int major = atoi(version_item->Value.ToCStr());
            if (major != 2)
                return;   // don't use the file on unsupported major version number
        }
        else
        {
            return;       // invalid file 
        }

        ProfileCache = root;   // store the database contents for traversal
    }
}
예제 #29
0
// Poplulates the local profile cache.  This occurs on the first access of the profile
// data.  All profile operations are performed against the local cache until the
// ProfileManager is released or goes out of scope at which time the cache is serialized
// to disk.
void ProfileManager::LoadCache(ProfileType device)
{
    Lock::Locker lockScope(&ProfileLock);

    ClearCache();

    String path = GetProfilePath(false);

    Ptr<JSON> root = *JSON::Load(path);
    if (!root || root->GetItemCount() < 3)
        return;

    // First read the file type and version to make sure this is a valid file
    JSON* item0 = root->GetFirstItem();
    JSON* item1 = root->GetNextItem(item0);
    JSON* item2 = root->GetNextItem(item1);

    if (item0->Name == "Oculus Profile Version")
    {
        int major = atoi(item0->Value.ToCStr());
        if (major > MAX_PROFILE_MAJOR_VERSION)
            return;   // don't parse the file on unsupported major version number
    }
    else
    {
        return;
    }

    DefaultProfile = item1->Value;

    // Read the number of profiles
    int   profileCount = (int)item2->dValue;
    JSON* profileItem  = item2;

    for (int p=0; p<profileCount; p++)
    {
        profileItem = root->GetNextItem(profileItem);
        if (profileItem == NULL)
            break;

        if (profileItem->Name == "Profile")
        {
            // Read the required Name field
            const char* profileName;
            JSON* item = profileItem->GetFirstItem();
        
            if (item && (item->Name == "Name"))
            {   
                profileName = item->Value;
            }
            else
            {
                return;   // invalid field
            }

            const char*   deviceName  = 0;
            bool          deviceFound = false;
            Ptr<Profile>  profile     = *CreateProfileObject(profileName, device, &deviceName);

            // Read the base profile fields.
            if (profile)
            {
                while (item = profileItem->GetNextItem(item), item)
                {
                    if (item->Type != JSON_Object)
                    {
                        profile->ParseProperty(item->Name, item->Value);
                    }
                    else
                    {   // Search for the matching device to get device specific fields
                        if (!deviceFound && deviceName && OVR_strcmp(item->Name, deviceName) == 0)
                        {
                            deviceFound = true;

                            for (JSON* deviceItem = item->GetFirstItem(); deviceItem;
                                 deviceItem = item->GetNextItem(deviceItem))
                            {
                                profile->ParseProperty(deviceItem->Name, deviceItem->Value);
                            }
                        }
                    }
                }
            }

            // Add the new profile
            ProfileCache.PushBack(profile);
        }
    }

    CacheDevice = device;
}
예제 #30
0
// Serializes the profiles to disk.
void ProfileManager::SaveCache()
{
    String path = GetProfilePath(true);
 
    Lock::Locker lockScope(&ProfileLock);

    Ptr<JSON> oldroot = *JSON::Load(path);
    if (oldroot)
    {
        if (oldroot->GetItemCount() >= 3)
        {
            JSON* item0 = oldroot->GetFirstItem();
            JSON* item1 = oldroot->GetNextItem(item0);
            oldroot->GetNextItem(item1);

            if (item0->Name == "Oculus Profile Version")
            {
                int major = atoi(item0->Value.ToCStr());
                if (major > MAX_PROFILE_MAJOR_VERSION)
                    oldroot.Clear();   // don't use the file on unsupported major version number
            }
            else
            {
                oldroot.Clear(); 
            }
        }
        else
        {
            oldroot.Clear();
        }
    }
    
    // Create a new json root
    Ptr<JSON> root = *JSON::CreateObject();
    root->AddNumberItem("Oculus Profile Version", PROFILE_VERSION);
    root->AddStringItem("CurrentProfile", DefaultProfile);
    root->AddNumberItem("ProfileCount", (double) ProfileCache.GetSize());

    // Generate a JSON subtree for each profile
    for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
    {
        Profile* profile = ProfileCache[i];

        // Write the base profile information
        JSON* json_profile = JSON::CreateObject();
        json_profile->Name = "Profile";
        json_profile->AddStringItem("Name", profile->Name);
        const char* gender;
        switch (profile->GetGender())
        {
            case Profile::Gender_Male:   gender = "Male"; break;
            case Profile::Gender_Female: gender = "Female"; break;
            default: gender = "Unspecified";
        }
        json_profile->AddStringItem("Gender", gender);
        json_profile->AddNumberItem("PlayerHeight", profile->PlayerHeight);
        json_profile->AddNumberItem("IPD", profile->IPD);

        const char* device_name = NULL;
        // Create a device-specific subtree for the cached device
        if (profile->Type == Profile_RiftDK1)
        {
            device_name = "RiftDK1";
            
            RiftDK1Profile* rift = (RiftDK1Profile*)profile;
            JSON* json_rift = JSON::CreateObject();
            json_profile->AddItem(device_name, json_rift);

            const char* eyecup = "A";
            switch (rift->EyeCups)
            {
                case EyeCup_A: eyecup = "A"; break;
                case EyeCup_B: eyecup = "B"; break;
                case EyeCup_C: eyecup = "C"; break;
            }
            json_rift->AddStringItem("EyeCup", eyecup);
            json_rift->AddNumberItem("LL", rift->LL);
            json_rift->AddNumberItem("LR", rift->LR);
            json_rift->AddNumberItem("RL", rift->RL);
            json_rift->AddNumberItem("RR", rift->RR);
        }
        else if (profile->Type == Profile_RiftDKHD)
        {
            device_name = "RiftDKHD";
            
            RiftDKHDProfile* rift = (RiftDKHDProfile*)profile;
            JSON* json_rift = JSON::CreateObject();
            json_profile->AddItem(device_name, json_rift);

            const char* eyecup = "A";
            switch (rift->EyeCups)
            {
                case EyeCup_A: eyecup = "A"; break;
                case EyeCup_B: eyecup = "B"; break;
                case EyeCup_C: eyecup = "C"; break;
            }
            json_rift->AddStringItem("EyeCup", eyecup);
            //json_rift->AddNumberItem("LL", rift->LL);
            //json_rift->AddNumberItem("LR", rift->LR);
            //json_rift->AddNumberItem("RL", rift->RL);
            //json_rift->AddNumberItem("RR", rift->RR);
        }

        // There may be multiple devices stored per user, but only a single
        // device is represented by this root.  We don't want to overwrite
        // the other devices so we need to examine the older root 
        // and merge previous devices into new json root
        if (oldroot)
        {
            JSON* old_profile = oldroot->GetFirstItem();
            while (old_profile)
            {
                if (old_profile->Name == "Profile")
                {
                    JSON* profile_name = old_profile->GetItemByName("Name");
                    if (profile_name && OVR_strcmp(profile->Name, profile_name->Value) == 0)
                    {   // Now that we found the user in the older root, add all the 
                        // object children to the new root - except for the one for the
                        // current device
                        JSON* old_item = old_profile->GetFirstItem();
                        while (old_item)
                        {
                            if (old_item->Type == JSON_Object 
                                && (device_name == NULL || OVR_strcmp(old_item->Name, device_name) != 0))
                            {
                                JSON* old_device = old_item;
                                old_item = old_profile->GetNextItem(old_item);

                                // remove the node from the older root to avoid multiple reference
                                old_device->RemoveNode();
                                // add the node pointer to the new root
                                json_profile->AddItem(old_device->Name, old_device);
                            }
                            else
                            {
                                old_item = old_profile->GetNextItem(old_item);
                            }
                        }

                        break;
                    }
                }

                old_profile = oldroot->GetNextItem(old_profile);
            }
        }

        // Add the completed user profile to the new root
        root->AddItem("Profile", json_profile);
    }

    // Save the profile to disk
    root->Save(path);
}