> For my project I think I prefer the first sulotion, can I have your example
> code please.

Sorry to take a while getting back to you - I had a lo-fi weekend.

Ok, the 'search engine' has three parts to it
1. A domain - basically, a big list of nested lists of things to search
2. A list processor - which goes through the domain  list
3. Search methods - which get applied to the things in the domain list.


Once you have a list of the castmembers you want to search, you need to go
through the list and do a search on each item in the list. The simplest and
fastest way of processing a list is recursively like this -

on findInList pList
  pListMX = pList.count
  repeat with i = 1 to pListMX
    thisEntry = pList[i]
    if listP(thisEntry) then findInList(thisEntry)
    else doSearchOn(thisEntry)
  end repeat
end

This is very fast. However, if its a really big list, then you might have
memory problems. More importantly, a big repeat loop like this, although
incredibly quick, will lock up the processor while its working. The
alternative way is to step through the list on stepFrame or similar.

This 'threaded' approach is much slower, but doesn't lock out other
processes. It works quickly if the framerate is high. I've pasted in a
"ListProcessor" parent script below which shows a way of processing big
nested lists. Its been setup to be used as an ancestor or daemon for another
object. In otherwords, it simpley works out which item in the list its up
to, the calls the specified object with the method that was passed to it as
a parameter when the search was initiated.

Its also desgined to handler lists of nested lists such as
  [["A", "B"], ["C", "D", "E"],["F"], "G", ["H", "I"]]

You could simplify it considerably if you are only processing flat lists.

Luke


------------------- ListProcessor Script ----------------------

property myRootList, myProcessMsg, myFinishedMsg, myServicedObj
property threaded_CurrentIndex, threaded_CurrentTrail, thread_Status

----// INIT & DESTROY

on new me
  myRootList = []
  myProcessMsg = VOID
  myFinishedMsg = VOID
  myServicedObj = VOID
  ---
  threaded_CurrentIndex = 0
  threaded_CurrentTrail = []  -- trail of branching points
  thread_Status = #finished
  (the actorList).append(me)
  return me
end

on mDestroy me
  (the actorList).deleteOne(me)
end

----// EVENT

on stepFrame me
  me.mRunThread()
end

----// PUBLIC

on mProcessList me, pList, pProcessMsg, pFinishMsg, pObj
  -- The object using the threadMgr must specify
  --   pList: the list to be processed
  --   pProcessMsg: the method to be called to process the list items
  --   pFinishMsg: the method to the called when the thread finishes
  --   pObj: the object that handles these calls
  
  myRootList = pList
  myProcessMsg = pProcessMsg
  myFinishedMsg = pFinishMsg
  myServicedObj = pObj
  ---
  if myRootList.count = 0 then
    if symbolP(myFinishedMsg) then call(myFinishedMsg, myServicedObj)
    --
  else
    threaded_CurrentIndex = 0
    threaded_CurrentTrail = []  -- trail of branching points
    thread_Status = #running
  end if
end


----// PRIVATE

on mRunThread me  
  currentSearchList = myRootList
  mx = threaded_CurrentTrail.count
  if mx > 0 then
    repeat with i = 1 to mx
      BranchPoint = threaded_CurrentTrail[i]
      currentSearchList = currentSearchList[BranchPoint]
    end repeat
  end if
  threaded_CurrentIndex = threaded_CurrentIndex + 1
  if threaded_CurrentIndex > currentSearchList.count then
    -- finished with current sub list
    if threaded_CurrentTrail.count > 0 then
      -- close current branch
      threaded_CurrentIndex =
threaded_CurrentTrail[threaded_CurrentTrail.count]
      threaded_CurrentTrail.deleteAt(threaded_CurrentTrail.count)
    else
      -- finish
      if thread_Status <> #finished then
        thread_Status = #finished
        if symbolP(myFinishedMsg) then call(myFinishedMsg, myServicedObj)
      end if
    end if
  else
    -- still processing current list
    thisEntry = currentSearchList[threaded_CurrentIndex]
    if listP(thisEntry) then
      -- open new branch
      threaded_CurrentTrail.append(threaded_CurrentIndex)
      threaded_CurrentIndex = 0
    else 
      -- found something to process
      call(myProcessMsg, myServicedObj, thisEntry)
    end if
  end if
end





-------------------- Example Script which uses the ListProcessor ------
property myListProcessor

on new me
  myListProcessor = script("ListProcessor").new()
  return me
end

on mTestListProcessor me
  aList = [["A", "B"], ["C", "D", "E"],["F"], "G", ["H", "I"]]
  myListProcessor.mProcessList(aList, #mProcessMethod, #mFinishMethod, me)
end

on mProcessMethod me, pListItem
  put "Found " & pListItem
end

on mFinishMethod me
  put "Finished!! "
end








[To remove yourself from this list, or to change to digest mode, go to
http://www.penworks.com/LUJ/lingo-l.cgi  To post messages to the list,
email [EMAIL PROTECTED]  (Problems, email [EMAIL PROTECTED])
Lingo-L is for learning and helping with programming Lingo.  Thanks!]

Reply via email to