Koodaan VB .net 3.5:lla käyttöliittymää erääseen mikrosiruprojektiin. HW:n rajapinnoista siirtyminen olio-ohjelmointiin ei ole kovinkaan kivutonta ja jään jatkuvasti soutamaan/huopaamaan ihme rakosiin. Etenkin Eventit ja delegaatit tuottavat harmaita hiuksia. Nyt olisi seuraavanlainen ongelma, toivottavasti joku tietävä ymmärtää:
Minulla on luokka, joka taltioi erilaisia tuloksia eri hakukriteerien perusteella. Jokainen hakukriteeri on oma instanssinsa ja instanssi säilöö tuottamansa tulokset. Kun tulos muuttuu, laukaistaan kyseisessä instanssissa ChangedEvent().
Näitä hakuinstansseja hallinnoi Moduli, joka säätelee tiedon syöttämistä hakuinstansseille. Ulkopuoliset, tiedosta KIINNOSTUNEET luokat voivat hallintomodulin kautta hakea asiankuuluvan hakuinstanssin ja pultata itsensä kiinni ChangedEventiin, jotta voi reagoida muutokseen omalla tavallaan.
Nyt olen törmännyt siihen ongelmaan, että koska funktiot palauttavat kopoioita varsionaisesta instanssista, en pysty SEURAAMAAN hallintomodulin tuottamia instansseja sen ulkopuolella. Eli en pysty pulttaamaan itseäni siihen oikeaan ChangedEventiin, vaan kopioon siitä, joka ei ikinä tietenkään laukea.
Varmaankin joudun muuttamaan toimintatyyliä jotenkin, mutta haluaisin säilyttää hakuinstanssien kapseloinnin. Eli ne voitaisiin säilöä tiedosta kiinnostuneissa luokissa, mutta hallintomodulin täytyy pystyä syöttämään suoraan näille instansseille raakatietoa. Olen kokeillut tätäkin, mutta en ole onnistunut taltioimaan ByRef tietoa indeksoitavaan muotoon varsinaisen funktion ulkopuolella. Esim. MyArray(X) = VariableRef tuottaa vain kopion referenssistä, ei varsinaista pointteria alkuperäiseen (siis siihen kapseloituun hakuinstanssiin).
pistäppä vähän koodia miten sä olet sen toteuttanut.
eli moduulista, luokastasi johon tulokset tallennetaan ja ChangedEvent():stä.
mielellään vaikka esimerkki yksittäisestä tallennustapahtumasta ja sen seuraamasta ChangedEvent():stä
ymmärsin että moduulissa käsitellään itse haku, tulos tallentuu luokkaasi ja se laukaisee tuon ChangedEvent():n
Tässä on idea, miten sitä yritin toteuttaa, mutta kopioituminen katkaisi eventtiketjun (muuten toimi).
Class SearchCaller MySearch = new Tallennus(Parameters) MySearch = SearchModule.InsertSearch(MySearch) 'MySearchin muuttumista halutaan jatkossa seurata reaktiivisesti AddHandler EventHandler, Addressof MySearch.ResultsChanged Module SearchModule public function IsertSearch(ByRef Seed As Tallennus) 'Katsotaan, onko olemassa identtinen hakutallennus, jos ei niin käytetään 'Annettua siementä. Eventtiketju katkeaa tässä, koska en saa pointeria 'työnnettyä takaisin kutsujalle If Exists = true then Tallennus = ExistingRef return Tallennus end function Public Sub NewData(ByVal Data) For Each Instance in Tallennukset Instance.AddResult(Data) next end sub Class Tallennus Public Event ResultsChanged(ByRef Tallennus) Public Sub AddResult(ByRef Messages() As Communicator.SerialMessage) 'Tässä välissä tallennusrutiini RaiseEvent ResultsChanged(Me) End Sub
no mun järki sanoisi että se jämähtää jos on olemassa identtinen hakutallennus, koska ei ole eventtiä joka seuraisi sitä että jos sisältö ei muutukkaan.
sulla on resultschanged eventti mutta ei lainkaan eventtiä sille jos sisältö pysyykin samana.
If Exists = true then Tallennus = ExistingRef
tekeekö se tuossa todellisuudessa mitään, vai pysyykö Tallennus entisellään jos identtinen hakutallennus on jo olemassa.
Moikka latesoft!
pari asiaa, jotka pistivä silmään näin äkkiseltään...
'... 'ehkä kannattaisi eliminoida mahdollisuus, että jäisi kantamaan... MySearch = Nothing '* MySearch = new Tallennus(Parameters) 'olisiko funktion tarkoitus palauttaa jotain...? Public Function InsertSearch(ByRef Seed As Tallennus) 'As Tyyppi? '(voisiko tyyppi olla vaikkapa MySearch) 'Exists mitä? ...ja mitä sitten jos Not Exists? If Exists = true then Tallennus = ExistingRef '[k]jos tyyppi ei ole 'MySearch' tuntuisi äkkipäätä loogiselta, 'että jos identtinen hakutallennus löytyy niin funktio palauttaisi 'vaikka stringin "don't do anything" ja jos vastaavuutta ei löydy 'niin Return olisi vaikka "do something"...[/k] RaiseEvent ResultsChanged(Me) 'ettei pääsisi syntymään mahdollisia päällekkäisyyksiä... RemoveHandler EventHandler, Addressof MySearch.ResultsChanged '*
Kiitos vastauksista. InsertSearchin tarkoitus oli palauttaa AINA sellainen Tallennus-instanssi, jonka eventtiä kannattaa seurata. TAvallaan kutsujaluokan antama MySearch käännettäisiin modulin osoitteistoon (mikä ei tuntunut onnistuvan). Onko niin, että jokaista eventiä varten voi tehdä vain yhden handlerin? Sehän nimittäin kaataa tämän idean jo heti.
Tänään joudun tekemään asialle jotain, mutta joudun keksimään menetelmän, jonka avulla SearchModule pystyy tekemään seuraavaa:
1. Jakamaan tietoa sitä etsiville instansseille. Voinhan sen tehdä niinkin, että hakija kutsuu funktiota, joka palauttaa hakutulokset.
2. Hyvin mielellään eventpohjainen päivitys. Eli tietoa etsivän ei tarvitse pollata jatkuvasti, onko uutta dataa, vaan kun uutta dataa ilmestyy, etsivä luokka saa ilmoituksen. Tämä on ollut pääasiallinen ongelma.
latesoft kirjoitti:
...Jokainen hakukriteeri on oma instanssinsa ja instanssi säilöö tuottamansa tulokset. Kun tulos muuttuu, laukaistaan kyseisessä instanssissa ChangedEvent().
latesoft kirjoitti:
Onko niin, että jokaista eventiä varten voi tehdä vain yhden handlerin? Sehän nimittäin kaataa tämän idean jo heti.
Eikä mitään kaada, idea on sinällään loistava...
Jos kerran eventin laukaisua yritetään vain ja ainoastaan silloin, kun tulos muuttuu niin mielestäni on aika loogista, että kun event on laukaistu handler pyyhkäistään 'nevadaan'. Kun tulos muuttuu ja käsittelijää tarvitaan, luodaan ko. instanssin tarpeita varten aina uusi mikä estää myös kopioiden syntymisen.
Eli handler luodaan vain jos InsertSearch-funktio palauttaa OK:ta (doesn't Exists). Identtisen hakutuloksen kohdatessaan funktion palautteeksi voi huoletta säätää Ei-OK:ta koska kaikki mahdollisten jatkotoimien tarvitsema tieto on jo säilössä...
Aihe on jo aika vanha, joten et voi enää vastata siihen.