Structures within Structures - can it be done?
I have created a structure to hold channel presets, with a name and a number. No problem. The thing I can't quite wrap my head around is how to create a structure WITHIN a structure. I was hoping to be able to create another structure to contain 6 different users each with their own custom presets, but when i tried to do it, I locked up not only Netlinx studio, but my PC as well, effectively corrupting the project and forcing me to extract from the src file. So...I really don't want that to happen again. I tried something like this:
I then tried to create a structure within a structure:
STRUCTURE _tvpreset //preset info
{
CHAR sChanName[15]
INTEGER nChanNum
}
DEFINE_VARIABLE
PERSISTENT _tvpreset uSATPresets[20] //20 presets to store #s
which gave me a structure with 2 elements(1 name, 1 number) to start with.I then tried to create a structure within a structure:
STRUCTURE _users
{
_tvpreset uTVusers //creating a data type already identified in a prior structure
CHAR sName //to describe the person selecting the presets info
}
It seems like it is possible, but am I looking at this backwards or something?
Comments
DEFINE_TYPE //_sSS_BrowseState STRUCTURE _sSS_BrowseState {// Browsing state information: INTEGER nContextSession ; LONG nNumLines ; // Number of lines for this browse session INTEGER nLevel ; // Current "level" for this browse session } DEFINE_TYPE //_sSS_DoExtOpcode STRUCTURE _sSS_DoExtOpcode { INTEGER nOpCode ; // Most extended commands INTEGER nIntParam1 ; INTEGER nIntParam2 ; // Specifically used for SS_DoExtCommand SLONG nParam1 ; } DEFINE_TYPE //_sSS_UI_DoCommand STRUCTURE _sSS_UI_DoCommand { INTEGER nOpCode ; INTEGER nParam1 ; CHAR cParam1[SS_LEN_Item] ; } DEFINE_TYPE //_sSS_QueueFile STRUCTURE _sSS_QueueFile { INTEGER nType ; // Specify either the URL *OR* the itemID to queue CHAR cItem[SS_LEN_URL] ; LONG nID_Item ; // Filtering criteria LONG nID_Genre ; LONG nID_Artist ; LONG nID_Album ; LONG nID_Plylist ; // Filtering criteria (via QueueFile API - if written) CHAR cGenre[SS_LEN_Genre] ; CHAR cArtist[SS_LEN_Artist] ; CHAR cAlbum[SS_LEN_Album] ; } // Packets sent from SlimServer module to caller DEFINE_TYPE //_sSS_StatusInfo STRUCTURE _sSS_StatusInfo {// Response to a status request: CHAR cPlayerName[32] ; // Player name (size can be increased if needed) CHAR cPlayerIP[15] ; // IP address of player CHAR cPlayTime[20] ; CHAR cID[20] ; CHAR cCanSeek[20] ; CHAR cPL_TmStamp[20] ; CHAR cPL_Mode[20] ; CHAR cTitle[20] ; CHAR cGenre[20] ; CHAR cArtist[20] ; CHAR cAlbum[20] ; CHAR cSeqNo[20] ; INTEGER nPlayer_Connected ; // Player currently connected? INTEGER nPower ; // Player currently powered on? INTEGER nSignalStrength ; // Signal Strength (1-100, 0 if not wireless) INTEGER nMode ; // Play mode (see SS_PlayMode_* constants) //INTEGER nSongTime ; // Seconds of song that have been played // INTEGER nSongDuration ; // Total seconds of current song INTEGER nSleepTime ; // Number of minutes player was set to sleep INTEGER nSleepRemaining ; // Number of minutes remaining prior to sleep (if sleepTime is set) SINTEGER nRate ; // Rate (Rewinding: <0, Fast Fwd: >1, Play: 1 INTEGER nMixVolume ; // Current Volume Setting: 0-100 INTEGER nIRVolume ; // Current Volume Setting: 0-40 (Like Squeezebox display) INTEGER nMixBalance ; // Reserved: Current Balance Setting: 0-100 INTEGER nMixBass ; // Reserved: Current Bass Setting: 0-100 INTEGER nMixTreble ; // Reserved: Current Treble Setting: 0-100 INTEGER nMixPitch ; // Reserved: Current Pitch Setting: 80-120 INTEGER nPlylistRepeat ; // Playlist Repeat State (0: Stop at end, 1: Repeat current song, 2: Repeat all songs) INTEGER nPlylistShuffle ; // Playlist Shuffle State (0: None, 1: Songs, 2: Albums) LONG nPlylistCurIndx ; // Index of currently played item (1 is first item) LONG nPlylistTracks ; // Total number of tracks in sSqzBox.sPlaylist } DEFINE_TYPE //_sSS_Playlist STRUCTURE _sSS_Playlist {// Response to a status sSqzBox.sPlaylist request: LONG nIndx ; // Index of this song in the sSqzBox.sPlaylist LONG nID ; // Internal database ID of item in sSqzBox.sPlaylist CHAR cTitle[SS_LEN_Title] ; // Remaining fields: Tag data CHAR cArtist[SS_LEN_Artist] ; CHAR cAlbum[SS_LEN_Album] ; CHAR cGenre[SS_LEN_Genre] ; CHAR cPath[128] ; LONG nSongTime LONG nSongDuration ; LONG nSentSongTime LONG nSentSongDuration ; INTEGER nRemote ; } DEFINE_TYPE //_sSS_UI_ErrorResult STRUCTURE _sSS_UI_ErrorResult {// Response if a UI command fails in some way INTEGER nLevel ; // Current depth/level of UI code INTEGER nErrCode ; // Error code from SlimServer UI component CHAR cErrText[SS_MAX_UI_errText] ; // Error text from SlimServer UI component } DEFINE_TYPE //_sSS_GetBrowseInfo STRUCTURE _sSS_GetBrowseInfo {// Packet to fetch browse information INTEGER nType ; // Type of fetch operation LONG nStartItem ; // Starting item number to fetch LONG nCountItem ; // Number of items to fetch for page INTEGER nSortTrack ; // If getting title list, sort by track? // Filtering criteria LONG nID_Artist ; LONG nID_Album ; LONG nID_Genre ; LONG nID_PlyList ; // Perform "search" (limit list of items returned to those containing search string) CHAR cListDir[SS_LEN_URL] ; // Directory/URL for sSqzBox.sPlaylist CHAR cSearch[SS_LEN_Item] ; // Search restriction text // Returned once query is performed LONG nMaxItems ; // Maximum number of items available } DEFINE_TYPE //_sUI_List STRUCTURE _sUI_List { CHAR cItem[MAX_NUM_BROWSE_LINES][SS_LEN_Item] ; CHAR cGenre[MAX_NUM_BROWSE_LINES][SS_LEN_Item] ; CHAR cArtist[MAX_NUM_BROWSE_LINES][SS_LEN_Item] ; CHAR cAlbum[MAX_NUM_BROWSE_LINES][SS_LEN_Item] ; CHAR cURL[MAX_NUM_BROWSE_LINES][SS_LEN_URL] ; LONG nID[MAX_NUM_BROWSE_LINES] ; LONG nDuration[MAX_NUM_BROWSE_LINES] ; // LONG ID_PlyList[MAX_NUM_BROWSE_LINES] ; } DEFINE_TYPE //_sSS_Player STRUCTURE _sSS_Player {// Player state information: INTEGER nDev_Instance ; CHAR cIP[21] ; CHAR cStrMAC[17] ; CHAR cArtHost[21] ; //CHAR cLstArtHost[21] ; CHAR cLstCmd[128] ; CHAR cJump[12] ; INTEGER nServerMAC[6] ; INTEGER nRealMAC[6] ; LONG nPort ; INTEGER nPower ; INTEGER nIP_ConnectState ; INTEGER nIP_ConnectAttempts ; INTEGER nUI_Active ; INTEGER nQ_HasItems ; INTEGER nListen_On ; INTEGER nNum_UIs ; INTEGER nDeBug ; } DEFINE_TYPE //sSqzBox_sStructure STRUCTURE _sStructure { _sSS_Player sPlayer ; _sSS_BrowseState sBrowseState ; _sSS_GetBrowseInfo sInfoSearch[MAX_UI_Level] ; _sUI_List sUI_List[MAX_UI_Level] ; _sSS_PlayList sPlaylist[2] ; _sSS_PlayList sOldPlaylist[2] ; _sSS_StatusInfo sStatus ; _sSS_StatusInfo sOldStatus } DEFINE_VARIABLE //STRUCTURES VOLATILE _sStructure sSqzBox ;The last structure contains all the previous declared structures which could also include structures if there was a need. I'm not sure how deep you can go but you can go pretty deep. It just makes writing a variable really, really long.
I tend to go lightly with it though; referencing an element three-four levels deep can get dang confusing, especially if you are working with arrays of structures (like I usually am). I find for simplicity's sake it's often easier to keep it at two levels, tops.
I agree with this. My poor addled brain gets lost in the endless dots and [] when working with the variables. I find that keeping them separate keeps me saner when in the program itself.
Every time you declare 300 variables at the top of a file there's a puppy massacre.
I much prefer embedded structures as it's so much easier to keep context and group related data. Maybe that's just me attempting to cling to anything that remotely resembles object orientation though.