示例#1
0
// for sound effects
unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath, bool bLoop/* = false*/)
{
	result r = E_FAILURE;
	string strFilePath = fullPathFromRelativePath(pszFilePath);
	unsigned int nRet = _Hash(strFilePath.c_str());

	preloadEffect(pszFilePath);

	EffectList::iterator p = s_List.find(nRet);
	if (p != s_List.end())
	{
		p->second->SetVolume((int) (s_fEffectsVolume * 99));
		int volume = p->second->GetVolume();

    	if (s_fEffectsVolume > 0.0f && volume == 0)
    	{
    		p->second->SetVolume(1);
    	}

	    if (AUDIOOUT_STATE_PLAYING == p->second->GetState())
		{
            return nRet; // Stop waste a lot of time, so just return.
	    	//r = p->second->Stop();
		}

	    if (s_fEffectsVolume > 0.0f)
	    {
	    	r = p->second->Play(bLoop);
	    }

    	if (IsFailed(r))
    	{
    		AppLog("play effect fails, error code = %d", r);
    	}
	}
	return nRet;
}
void CMasternodeSync::BumpAssetLastTime(const std::string& strFuncName)
{
    if(IsSynced() || IsFailed()) return;
    nTimeLastBumped = GetTime();
    LogPrint(MCLog::MN, "CMasternodeSync::BumpAssetLastTime -- %s\n", strFuncName);
}
void CMasternodeSync::ProcessTick(CConnman& connman)
{
    static int nTick = 0;
    if(nTick++ % MASTERNODE_SYNC_TICK_SECONDS != 0) return;

    // reset the sync process if the last call to this function was more than 60 minutes ago (client was in sleep mode)
    static int64_t nTimeLastProcess = GetTime();
    if(GetTime() - nTimeLastProcess > 60*60) {
        LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- WARNING: no actions for too long, restarting sync...\n");
        Reset();
        SwitchToNextAsset(connman);
        nTimeLastProcess = GetTime();
        return;
    }
    nTimeLastProcess = GetTime();

    // reset sync status in case of any other sync failure
    if(IsFailed()) {
        if(nTimeLastFailure + (1*60) < GetTime()) { // 1 minute cooldown after failed sync
            LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- WARNING: failed to sync, trying again...\n");
            Reset();
            SwitchToNextAsset(connman);
        }
        return;
    }

    // gradually request the rest of the votes after sync finished
    if(IsSynced()) {
        std::vector<CNode*> vNodesCopy = connman.CopyNodeVector(CConnman::FullyConnectedOnly);
        governance.RequestGovernanceObjectVotes(vNodesCopy, connman);
        connman.ReleaseNodeVector(vNodesCopy);
        return;
    }

    // Calculate "progress" for LOG reporting / GUI notification
    double nSyncProgress = double(nRequestedMasternodeAttempt + (nRequestedMasternodeAssets - 1) * 8) / (8*4);
    LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d nSyncProgress %f\n", nTick, nRequestedMasternodeAssets, nRequestedMasternodeAttempt, nSyncProgress);
    uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress);

    std::vector<CNode*> vNodesCopy = connman.CopyNodeVector(CConnman::FullyConnectedOnly);

    for (auto& pnode : vNodesCopy)
    {
        // Don't try to sync any data from outbound "masternode" connections -
        // they are temporary and should be considered unreliable for a sync process.
        // Inbound connection this early is most likely a "masternode" connection
        // initiated from another node, so skip it too.
        if(pnode->fMasternode || (fMasternodeMode && pnode->fInbound)) continue;
        
        const CNetMsgMaker msgMaker(pnode->GetSendVersion());
        
        // QUICK MODE (REGTEST ONLY!)
        if(Params().NetworkIDString() == CBaseChainParams::REGTEST)
        {
            if(nRequestedMasternodeAttempt <= 2) {
                mnodeman.DsegUpdate(pnode, connman);
            } else if(nRequestedMasternodeAttempt < 4) {
                //sync payment votes
                if(pnode->nVersion == 70018) {
                    connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit())); //sync payment votes
                } else {
                    connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC)); //sync payment votes
                }
                // connman.PushMessage(pnode, NetMsgType::MASTERNODEPAYMENTSYNC, nMnCount); //sync payment votes
                SendGovernanceSyncRequest(pnode, connman);
            } else {
                nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            }
            nRequestedMasternodeAttempt++;
            connman.ReleaseNodeVector(vNodesCopy);
            return;
        }

        // NORMAL NETWORK MODE - TESTNET/MAINNET
        {
            if(netfulfilledman.HasFulfilledRequest(pnode->addr, "full-sync")) {
                // We already fully synced from this node recently,
                // disconnect to free this connection slot for another peer.
                pnode->fDisconnect = true;
                LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- disconnecting from recently synced peer=%d\n", pnode->GetId());
                continue;
            }

            // INITIAL TIMEOUT

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_WAITING) {
                if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) {
                    // At this point we know that:
                    // a) there are peers (because we are looping on at least one of them);
                    // b) we waited for at least MASTERNODE_SYNC_TIMEOUT_SECONDS since we reached
                    //    the headers tip the last time (i.e. since we switched from
                    //     MASTERNODE_SYNC_INITIAL to MASTERNODE_SYNC_WAITING and bumped time);
                    // c) there were no blocks (UpdatedBlockTip, NotifyHeaderTip) or headers (AcceptedBlockHeader)
                    //    for at least MASTERNODE_SYNC_TIMEOUT_SECONDS.
                    // We must be at the tip already, let's move to the next asset.
                    SwitchToNextAsset(connman);
                }
            }

            // MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
                LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped);
                // check for timeout first
                if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) {
                    LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if (nRequestedMasternodeAttempt == 0) {
                        LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- ERROR: failed to sync %s\n", GetAssetName());
                        // there is no way we can continue without masternode list, fail here and try later
                        Fail();
                        connman.ReleaseNodeVector(vNodesCopy);
                        return;
                    }
                    SwitchToNextAsset(connman);
                    connman.ReleaseNodeVector(vNodesCopy);
                    return;
                }
                
                // request from three peers max
                if (nRequestedMasternodeAttempt > 2) {
                    connman.ReleaseNodeVector(vNodesCopy);
                    return;
                }

                // only request once from each peer
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-list-sync")) continue;
                netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-list-sync");

                if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
                nRequestedMasternodeAttempt++;

                mnodeman.DsegUpdate(pnode, connman);

                connman.ReleaseNodeVector(vNodesCopy);
                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }

            // MNW : SYNC MASTERNODE PAYMENT VOTES FROM OTHER CONNECTED CLIENTS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
                LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped);
                // check for timeout first
                // This might take a lot longer than MASTERNODE_SYNC_TIMEOUT_SECONDS due to new blocks,
                // but that should be OK and it should timeout eventually.
                if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) {
                    LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if (nRequestedMasternodeAttempt == 0) {
                        LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- ERROR: failed to sync %s\n", GetAssetName());
                        // probably not a good idea to proceed without winner list
                        Fail();
                        connman.ReleaseNodeVector(vNodesCopy);
                        return;
                    }
                    SwitchToNextAsset(connman);
                    connman.ReleaseNodeVector(vNodesCopy);
                    return;
                }

                // check for data
                // if mnpayments already has enough blocks and votes, switch to the next asset
                // try to fetch data from at least two peers though
                if(nRequestedMasternodeAttempt > 1 && mnpayments.IsEnoughData()) {
                    LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets);
                    SwitchToNextAsset(connman);
                    connman.ReleaseNodeVector(vNodesCopy);
                    return;
                }
                
                // request from three peers max
                if (nRequestedMasternodeAttempt > 2) {
                    connman.ReleaseNodeVector(vNodesCopy);
                    return;
                }

                // only request once from each peer
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-payment-sync")) continue;
                netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-payment-sync");

                if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
                nRequestedMasternodeAttempt++;

                // ask node for all payment votes it has (new nodes will only return votes for future payments)
                //sync payment votes
                if(pnode->nVersion == 70018) {
                    connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit()));
                } else {
                    connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC));
                }
                // connman.PushMessage(pnode, NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit());
                // ask node for missing pieces only (old nodes will not be asked)
                mnpayments.RequestLowDataPaymentBlocks(pnode, connman);

                connman.ReleaseNodeVector(vNodesCopy);
                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }

            // GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE) {
                LogPrint(MCLog::GOV, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped);

                // check for timeout first
                if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) {
                    LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if(nRequestedMasternodeAttempt == 0) {
                        LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- WARNING: failed to sync %s\n", GetAssetName());
                        // it's kind of ok to skip this for now, hopefully we'll catch up later?
                    }
                    SwitchToNextAsset(connman);
                    connman.ReleaseNodeVector(vNodesCopy);
                    return;
                }

                // only request obj sync once from each peer, then request votes on per-obj basis
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) {
                    int nObjsLeftToAsk = governance.RequestGovernanceObjectVotes(pnode, connman);
                    static int64_t nTimeNoObjectsLeft = 0;
                    // check for data
                    if(nObjsLeftToAsk == 0) {
                        static int nLastTick = 0;
                        static int nLastVotes = 0;
                        if(nTimeNoObjectsLeft == 0) {
                            // asked all objects for votes for the first time
                            nTimeNoObjectsLeft = GetTime();
                        }
                        // make sure the condition below is checked only once per tick
                        if(nLastTick == nTick) continue;
                        if(GetTime() - nTimeNoObjectsLeft > MASTERNODE_SYNC_TIMEOUT_SECONDS &&
                            governance.GetVoteCount() - nLastVotes < std::max(int(0.0001 * nLastVotes), MASTERNODE_SYNC_TICK_SECONDS)
                        ) {
                            // We already asked for all objects, waited for MASTERNODE_SYNC_TIMEOUT_SECONDS
                            // after that and less then 0.01% or MASTERNODE_SYNC_TICK_SECONDS
                            // (i.e. 1 per second) votes were recieved during the last tick.
                            // We can be pretty sure that we are done syncing.
                            LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- asked for all objects, nothing to do\n", nTick, nRequestedMasternodeAssets);
                            // reset nTimeNoObjectsLeft to be able to use the same condition on resync
                            nTimeNoObjectsLeft = 0;
                            SwitchToNextAsset(connman);
                            connman.ReleaseNodeVector(vNodesCopy);
                            return;
                        }
                        nLastTick = nTick;
                        nLastVotes = governance.GetVoteCount();
                    }
                    continue;
                }
                netfulfilledman.AddFulfilledRequest(pnode->addr, "governance-sync");

                if (pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) continue;
                nRequestedMasternodeAttempt++;

                SendGovernanceSyncRequest(pnode, connman);

                connman.ReleaseNodeVector(vNodesCopy);
                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }
        }
    }
    // looped through all nodes, release them
    connman.ReleaseNodeVector(vNodesCopy);
}
示例#4
0
/* virtual */
OP_STATUS
ES_JavascriptURLThread::EvaluateThread()
{
	OP_STATUS ret = OpStatus::OK;

	switch (eval_state)
	{
	case STATE_INITIAL:
		{
			eval_state = STATE_SET_PROGRAM;

#ifdef USER_JAVASCRIPT
			DOM_Environment *environment = scheduler->GetFramesDocument()->GetDOMEnvironment();

			RETURN_IF_ERROR(environment->HandleJavascriptURL(this));

			if (IsBlocked())
				return OpStatus::OK;
#endif // USER_JAVASCRIPT
		}
		// fall through

	case STATE_SET_PROGRAM:
		if (source)
		{
			ES_ProgramText program_text;

			program_text.program_text = source;
			program_text.program_text_length = uni_strlen(source);

			ES_Runtime *runtime = scheduler->GetRuntime();

			ES_Program *program;
			OP_STATUS status;

			ES_Runtime::CompileProgramOptions options;
			options.generate_result = TRUE;
			options.global_scope = FALSE;
			options.script_type = SCRIPT_TYPE_JAVASCRIPT_URL;
			options.when = UNI_L("while loading");
			options.script_url = &url;
#ifdef ECMASCRIPT_DEBUGGER
			options.reformat_source = g_ecmaManager->GetWantReformatScript(runtime);
#endif // ECMASCRIPT_DEBUGGER

			if (OpStatus::IsSuccess(status = runtime->CompileProgram(&program_text, 1, &program, options)))
				if (program)
					SetProgram(program);
				else
					status = OpStatus::ERR;

			if (OpStatus::IsMemoryError(status))
			{
				is_completed = is_failed = TRUE;
				return status;
			}
			else if (OpStatus::IsError(status))
			{
				is_completed = is_failed = TRUE;
				return OpStatus::OK;
			}
		}
		eval_state = STATE_EVALUATE;
		// fall through

	case STATE_EVALUATE:
		{
			ret = ES_Thread::EvaluateThread();
			if (OpStatus::IsError(ret))
			{
				eval_state = STATE_HANDLE_RESULT;
				is_completed = TRUE;
				break;
			}
			else if (IsCompleted())
			{
				if (IsFailed())
				{
					eval_state = STATE_DONE;
					break;
				}
				else
#ifdef USER_JAVASCRIPT
					eval_state = STATE_SEND_USER_JS_AFTER;
#else // USER_JAVASCRIPT
					eval_state = STATE_HANDLE_RESULT;
#endif // USER_JAVASCRIPT
			}
			else
				break;
		}
		// fall through

#ifdef USER_JAVASCRIPT
	case STATE_SEND_USER_JS_AFTER:
		{
			DOM_Environment *environment = scheduler->GetFramesDocument()->GetDOMEnvironment();

			RETURN_IF_ERROR(environment->HandleJavascriptURLFinished(this));

			eval_state = STATE_HANDLE_RESULT;

			if (IsBlocked())
			{
				is_completed = FALSE;
				break;
			}
		}
		// fall through
#endif // USER_JAVASCRIPT

	case STATE_HANDLE_RESULT:
		{
			is_completed = TRUE;
			const uni_char *use_result = NULL;

#ifdef USER_JAVASCRIPT
			if (has_result)
				use_result = result;
			else
#endif // USER_JAVASCRIPT
				if (ReturnedValue())
				{
					ES_Value return_value;

					RETURN_IF_ERROR(GetReturnedValue(&return_value));

					if (return_value.type == VALUE_STRING)
						use_result = return_value.value.string;
				}

			FramesDocument *frames_doc = GetFramesDocument();
			OP_ASSERT(frames_doc); // Since we're executing we must be in a document
			if (use_result)
			{
				if (write_result_to_document)
				{
					// The HTML5 spec says that we should load this data exactly as if it had come
					// from an HTTP connection with content type text/html and status 200. This
					// is a very bad approximation of that.
					BOOL is_busy = scheduler->IsDraining() || !frames_doc->IsCurrentDoc();
					write_result_to_document = FALSE; // Since it's enough to do it once
					frames_doc->SetWaitForJavascriptURL(FALSE);

					if (!is_busy)
						if (HLDocProfile *hld_profile = frames_doc->GetHLDocProfile())
							is_busy = hld_profile->GetESLoadManager()->GetScriptGeneratingDoc();

					if (!is_busy)
					{
						if (GetOriginInfo().open_in_new_window)
							RETURN_IF_ERROR(DOM_Environment::OpenWindowWithData(use_result, frames_doc, this, GetOriginInfo().is_user_requested));
						else
						{
							// The ESOpen()/ESClose() calls are just done in order to create an
							// empty document in The Right Way(tm) in order to parse some data
							// into it as if it had been loaded from a URL, and not to set up
							// a document.write call like they are usually used for.
							ESDocException doc_exception; // Ignored
							RETURN_IF_ERROR(frames_doc->ESOpen(scheduler->GetRuntime(), &url, is_reload, NULL, NULL, &doc_exception));

							FramesDocument *new_frames_doc = frames_doc->GetDocManager()->GetCurrentDoc();
							RETURN_IF_ERROR(new_frames_doc->ESClose(scheduler->GetRuntime()));

							SetBlockType(ES_BLOCK_NONE);

							if (frames_doc != new_frames_doc)
								RETURN_IF_ERROR(new_frames_doc->GetLogicalDocument()->ParseHtmlFromString(use_result, uni_strlen(use_result), FALSE, FALSE, FALSE));
							else
								OP_ASSERT(!"ESOpen might have failed, but if it didn't then we're stuck with a hung thread in a document and nothing will work");

							new_frames_doc->ESStoppedGeneratingDocument();
						}
					}
				}

				if (write_result_to_url)
				{
					if (want_utf8)
					{
						UTF16toUTF8Converter converter;

						unsigned length = uni_strlen(use_result) * sizeof source[0], needed = converter.BytesNeeded(use_result, length);
						converter.Reset();

						char *data;
						if (needed < g_memory_manager->GetTempBufLen())
							data = (char *) g_memory_manager->GetTempBuf();
						else
							data = OP_NEWA(char, needed);

						if (!data)
						{
							ret = OpStatus::ERR_NO_MEMORY;
							break;
						}
						else
						{
							int read, written = converter.Convert(use_result, length, data, needed, &read);

							url.WriteDocumentData(URL::KNormal, data, written);
							url.WriteDocumentDataFinished();

							if (data != g_memory_manager->GetTempBuf())
								OP_DELETEA(data);
						}
					}
					else
					{
						url.WriteDocumentData(URL::KNormal, use_result, uni_strlen(use_result));
						url.WriteDocumentDataFinished();
					}
				}
			}
			else if (write_result_to_document)
			{
				// The HTML5 spec says this should be handled as a HTTP status 204, NO_CONTENT
				frames_doc->GetMessageHandler()->PostMessage(MSG_URL_LOADING_FAILED, url.Id(), DH_ERRSTR(SI,ERR_HTTP_NO_CONTENT));
				frames_doc->SetWaitForJavascriptURL(FALSE);
				write_result_to_document = FALSE; // Since it's done and we don't want to do it again.
			}

			eval_state = STATE_DONE;
		}
   void TaskActorGameEvent::HandleGameEvent(const dtGame::Message &msg)
   {
      const dtGame::GameEventMessage &eventMsg = static_cast<const dtGame::GameEventMessage&>(msg);

      if(eventMsg.GetGameEvent() == NULL)
      {
         LOG_WARNING("HandleGameEvent: Game event message contained a NULL game event.");
         return;
      }

      if( ! mGameEvent.valid() && ! mGameEventFail.valid() )
      {
         LOG_WARNING("HandleGameEvent: Game event task actor has NULL game events.  Perhaps it was "
                    " assigned to the task before being added to the event manager.");
         return;
      }

      // Determine which event has been received.
      const dtCore::UniqueId& eventId = eventMsg.GetGameEvent()->GetUniqueId();
      bool isFailEvent = false;
      if( mGameEvent.valid() && eventId == mGameEvent->GetUniqueId() )
      {
         // DO NOTHING.
      }
      else if( mGameEventFail.valid() && eventId == mGameEventFail->GetUniqueId() )
      {
         isFailEvent = true;
      }
      else
      {
         // Not an event to act upon.
         return;
      }

      //If we got here we have a game event we were looking for.  So, all we need to do
      //is track the number of times we got the event, and if it reaches the min occurances
      //attempt to mark ourselves complete.
      TaskActorProxy &proxy = static_cast<TaskActorProxy&>(GetGameActorProxy());
      if(!IsComplete() && !IsFailed())
      {
         if(proxy.RequestScoreChange(proxy,proxy))
         {
            if( isFailEvent ) // Fail event
            {
               SetFailed( true );
            }
            else // Complete Event
            {
               mNumTimesEventFired++;
               float newScore = (float)mNumTimesEventFired / (float)mMinOccurances;
               if (newScore >= GetPassingScore())
                  SetComplete(true);

               SetScore(newScore);
            }

            // Notify the system that the task state has changed.
            proxy.NotifyScoreChanged(proxy);
            proxy.NotifyFullActorUpdate();
         }
      }
   }
示例#6
0
文件: fs.cpp 项目: alexnikleo/scummvm
bool BadaFilesystemNode::getChildren(AbstractFSList &myList,
																		 ListMode mode, bool hidden) const {
	AppAssert(isDirectory());

	bool result = false;

	if (_isVirtualDir && mode != Common::FSNode::kListFilesOnly) {
		// present well known BADA file system areas
		if (_path == PATH_ROOT) {
			myList.push_back(new BadaFilesystemNode(PATH_HOME));
			myList.push_back(new BadaFilesystemNode(PATH_HOME_EXT));
			myList.push_back(new BadaFilesystemNode(PATH_MEDIA));
			myList.push_back(new BadaFilesystemNode(PATH_CARD));
			result = true; // no more entries
		} else if (_path == PATH_CARD) {
			myList.push_back(new BadaFilesystemNode(PATH_CARD_MEDIA));
			result = true; // no more entries
		} else if (_path == PATH_HOME) {
			// ensure share path is always included
			myList.push_back(new BadaFilesystemNode(PATH_HOME_SHARE));
			myList.push_back(new BadaFilesystemNode(PATH_HOME_SHARE2));
		}
	}

	if (!result) {
		DirEnumerator *pDirEnum = 0;
		Directory *pDir = new Directory();

		// open directory
		if (IsFailed(pDir->Construct(_unicodePath))) {
			AppLog("Failed to open directory: %S", _unicodePath.GetPointer());
		} else {
			// read all directory entries
			pDirEnum = pDir->ReadN();
			if (pDirEnum) {
				result = true;
			}

			// loop through all directory entries
			while (pDirEnum && pDirEnum->MoveNext() == E_SUCCESS) {
				DirEntry dirEntry = pDirEnum->GetCurrentDirEntry();

				// skip 'invisible' files if necessary
				Osp::Base::String fileName = dirEntry.GetName();

				if (fileName[0] == '.' && !hidden) {
					continue;
				}

				// skip '.' and '..' to avoid cycles
				if (fileName == L"." || fileName == L"..") {
					continue;
				}

				// Honor the chosen mode
				if ((mode == Common::FSNode::kListFilesOnly && dirEntry.IsDirectory()) ||
						(mode == Common::FSNode::kListDirectoriesOnly && !dirEntry.IsDirectory())) {
					continue;
				}
				myList.push_back(new BadaFilesystemNode(_path, fromString(fileName)));
			}
		}

		// cleanup
		if (pDirEnum) {
			delete pDirEnum;
		}

		// close the opened directory
		if (pDir) {
			delete pDir;
		}
	}

	return result;
}