nuclear@0: /************************************************************************************ nuclear@0: nuclear@0: Filename : OVR_Profile.h nuclear@0: Content : Structs and functions for loading and storing device profile settings nuclear@0: Created : February 14, 2013 nuclear@0: Notes : nuclear@0: Profiles are used to store per-user settings that can be transferred and used nuclear@0: across multiple applications. For example, player IPD can be configured once nuclear@0: and reused for a unified experience across games. Configuration and saving of profiles nuclear@0: can be accomplished in game via the Profile API or by the official Oculus Configuration nuclear@0: Utility. nuclear@0: nuclear@0: Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. nuclear@0: nuclear@0: Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); nuclear@0: you may not use the Oculus VR Rift SDK except in compliance with the License, nuclear@0: which is provided at the time of installation or download, or which nuclear@0: otherwise accompanies this software in either electronic or hard copy form. nuclear@0: nuclear@0: You may obtain a copy of the License at nuclear@0: nuclear@0: http://www.oculusvr.com/licenses/LICENSE-3.2 nuclear@0: nuclear@0: Unless required by applicable law or agreed to in writing, the Oculus VR SDK nuclear@0: distributed under the License is distributed on an "AS IS" BASIS, nuclear@0: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. nuclear@0: See the License for the specific language governing permissions and nuclear@0: limitations under the License. nuclear@0: nuclear@0: ************************************************************************************/ nuclear@0: nuclear@0: #ifndef OVR_Profile_h nuclear@0: #define OVR_Profile_h nuclear@0: nuclear@0: #include "OVR_CAPI_Keys.h" nuclear@0: nuclear@0: #include "Sensors/OVR_DeviceConstants.h" nuclear@0: #include "Kernel/OVR_String.h" nuclear@0: #include "Kernel/OVR_RefCount.h" nuclear@0: #include "Kernel/OVR_Array.h" nuclear@0: #include "Kernel/OVR_StringHash.h" nuclear@0: #include "Kernel/OVR_System.h" nuclear@0: nuclear@0: namespace OVR { nuclear@0: nuclear@0: class HMDInfo; // Opaque forward declaration nuclear@0: class Profile; nuclear@0: class JSON; nuclear@0: nuclear@0: nuclear@0: // Device key for looking up profiles nuclear@0: struct ProfileDeviceKey nuclear@0: { nuclear@0: ProfileDeviceKey(const HMDInfo* info); nuclear@0: nuclear@0: // Initialized properly? nuclear@0: bool Valid; nuclear@0: nuclear@0: // The HMD type nuclear@0: HmdTypeEnum HmdType; nuclear@0: nuclear@0: // This is the 12 character serial number printed on the HMD nuclear@0: String PrintedSerial; nuclear@0: nuclear@0: // This is the product name string of the USB sensor device nuclear@0: // Note: It has been modified from the original to remove spaces and strip off "Oculus" nuclear@0: String ProductName; nuclear@0: nuclear@0: // This is the product id from the HID info of the USB sensor device nuclear@0: unsigned ProductId; nuclear@0: nuclear@0: static String SanitizeProductName(String productName); nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: // ----------------------------------------------------------------------------- nuclear@0: // ***** ProfileManager nuclear@0: nuclear@0: // Profiles are interfaced through a ProfileManager object. Applications should nuclear@0: // create a ProfileManager each time they intend to read or write user profile data. nuclear@0: // The scope of the ProfileManager object defines when disk I/O is performed. Disk nuclear@0: // reads are performed on the first profile access and disk writes are performed when nuclear@0: // the ProfileManager goes out of scope. All profile interactions between these times nuclear@0: // are performed in local memory and are fast. A typical profile interaction might nuclear@0: // look like this: nuclear@0: // nuclear@0: // { nuclear@0: // Ptr pm = *ProfileManager::Create(); nuclear@0: // Ptr profile = pm->LoadProfile(Profile_RiftDK1, nuclear@0: // pm->GetDefaultProfileName(Profile_RiftDK1)); nuclear@0: // if (profile) nuclear@0: // { // Retrieve the current profile settings nuclear@0: // } nuclear@0: // } // Profile will be destroyed and any disk I/O completed when going out of scope nuclear@0: class ProfileManager : public NewOverrideBase, public SystemSingletonBase nuclear@0: { nuclear@0: friend class OVR::SystemSingletonBase; nuclear@0: nuclear@0: protected: nuclear@0: ProfileManager(bool sys_register); nuclear@0: virtual ~ProfileManager(); nuclear@0: virtual void OnSystemDestroy(); nuclear@0: nuclear@0: protected: nuclear@0: // Synchronize ProfileManager access since it may be accessed from multiple threads, nuclear@0: // as it's shared through DeviceManager. nuclear@0: Lock ProfileLock; nuclear@0: Ptr ProfileCache; nuclear@0: bool Changed; nuclear@0: String TempBuff; nuclear@0: String BasePath; nuclear@0: nuclear@0: public: nuclear@0: // In the service process it is important to set the base path because this cannot be detected automatically nuclear@0: void SetBasePath(String basePath); nuclear@0: nuclear@0: int GetUserCount(); nuclear@0: const char* GetUser(unsigned int index); nuclear@0: bool CreateUser(const char* user, const char* name); nuclear@0: bool HasUser(const char* user); nuclear@0: bool RemoveUser(const char* user); nuclear@0: const char* GetDefaultUser(const ProfileDeviceKey& deviceKey); nuclear@0: bool SetDefaultUser(const ProfileDeviceKey& deviceKey, const char* user); nuclear@0: nuclear@0: virtual Profile* CreateProfile(); nuclear@0: Profile* GetProfile(const ProfileDeviceKey& deviceKey, const char* user); nuclear@0: Profile* GetDefaultUserProfile(const ProfileDeviceKey& deviceKey); nuclear@0: Profile* GetDefaultProfile(HmdTypeEnum device); nuclear@0: Profile* GetTaggedProfile(const char** key_names, const char** keys, int num_keys); nuclear@0: bool SetTaggedProfile(const char** key_names, const char** keys, int num_keys, Profile* profile); nuclear@0: nuclear@0: // Force re-reading the settings nuclear@0: void Read(); nuclear@0: nuclear@0: protected: nuclear@0: // Force writing the settings nuclear@0: void ClearProfileData(); nuclear@0: void Save(); nuclear@0: nuclear@0: String GetProfilePath(); nuclear@0: void LoadCache(bool create); nuclear@0: void LoadV1Profiles(JSON* v1); nuclear@0: const char* GetDefaultUser(const char* product, const char* serial); nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: //------------------------------------------------------------------- nuclear@0: // ***** Profile nuclear@0: nuclear@0: // The base profile for all users. This object is not created directly. nuclear@0: // Instead derived device objects provide add specific device members to nuclear@0: // the base profile nuclear@0: class Profile : public RefCountBase nuclear@0: { nuclear@0: protected: nuclear@0: OVR::Hash ValMap; nuclear@0: OVR::Array Values; nuclear@0: OVR::String TempVal; nuclear@0: String BasePath; nuclear@0: nuclear@0: public: nuclear@0: ~Profile(); nuclear@0: nuclear@0: int GetNumValues(const char* key) const; nuclear@0: const char* GetValue(const char* key); nuclear@0: char* GetValue(const char* key, char* val, int val_length) const; nuclear@0: bool GetBoolValue(const char* key, bool default_val) const; nuclear@0: int GetIntValue(const char* key, int default_val) const; nuclear@0: float GetFloatValue(const char* key, float default_val) const; nuclear@0: int GetFloatValues(const char* key, float* values, int num_vals) const; nuclear@0: double GetDoubleValue(const char* key, double default_val) const; nuclear@0: int GetDoubleValues(const char* key, double* values, int num_vals) const; nuclear@0: nuclear@0: void SetValue(const char* key, const char* val); nuclear@0: void SetBoolValue(const char* key, bool val); nuclear@0: void SetIntValue(const char* key, int val); nuclear@0: void SetFloatValue(const char* key, float val); nuclear@0: void SetFloatValues(const char* key, const float* vals, int num_vals); nuclear@0: void SetDoubleValue(const char* key, double val); nuclear@0: void SetDoubleValues(const char* key, const double* vals, int num_vals); nuclear@0: nuclear@0: bool IsDefaultProfile(); nuclear@0: nuclear@0: bool Close(); nuclear@0: nuclear@0: protected: nuclear@0: Profile(String basePath) : nuclear@0: BasePath(basePath) nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: void SetValue(JSON* val); nuclear@0: nuclear@0: static bool LoadProfile(const ProfileDeviceKey& deviceKey, nuclear@0: const char* user, nuclear@0: Profile** profile); nuclear@0: void CopyItems(JSON* root, String prefix); nuclear@0: nuclear@0: bool LoadDeviceFile(unsigned int device_id, const char* serial); nuclear@0: bool LoadDeviceProfile(const ProfileDeviceKey& deviceKey); nuclear@0: nuclear@0: bool LoadProfile(JSON* root, nuclear@0: const char* user, nuclear@0: const char* device_model, nuclear@0: const char* device_serial); nuclear@0: nuclear@0: bool LoadUser(JSON* root, nuclear@0: const char* user, nuclear@0: const char* device_name, nuclear@0: const char* device_serial); nuclear@0: nuclear@0: friend class ProfileManager; nuclear@0: friend class WProfileManager; nuclear@0: }; nuclear@0: nuclear@0: // This path should be passed into the ProfileManager nuclear@0: String GetBaseOVRPath(bool create_dir); nuclear@0: nuclear@0: nuclear@0: } // namespace OVR nuclear@0: nuclear@0: #endif // OVR_Profile_h