These are chat archives for AvaloniaUI/Avalonia

10th
May 2016
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 00:46
hey guys
on the RenderTarget my public override DrawingContext CreateDrawingContext() is never called... is there something clear that we are probably missing here?
it is never called and we never get anything rendered...
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 00:54
@grokys @jazzay any idea?
Jason Jarvis
@jazzay
May 10 2016 02:21
Did you return your RenderTarget from your implementation of IPlatformRenderInterface.CreateRenderer?
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 02:29
yeah we did
I completed erased everything and now we are redoing everything to see what could possible be wrong
Jason Jarvis
@jazzay
May 10 2016 03:10
and did you bootstrap the the application/platforms similar to other sample apps?
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 04:33
@jazzay we almost got it to work
[01:29:31.026][UNHANDLED EXCEPTION] OmniXaml.LoadException: Error loading XAML: OmniXaml.ParseException: The type "{:KeyboardNavigation} cannot be found"
  at OmniXaml.Typing.TypeRepository.GetByPrefix (System.String prefix, System.String typeName) [0x00052] in <filename unknown>:0 
  at OmniXaml.RuntimeTypeSource.GetByPrefix (System.String prefix, System.String typeName) [0x00006] in <filename unknown>:0 
  at Perspex.Markup.Xaml.Context.PerspexRuntimeTypeSource.GetByPrefix (System.String prefix, System.String typeName) [0x00000] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser.GetMemberForDottedLocator (OmniXaml.Typing.PropertyLocator propertyLocator) [0x00018] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser.ConvertAttributeToNode (OmniXaml.Typing.XamlType containingType, OmniXaml.Parsers.ProtoParser.AttributeAssignment rawAttributeAssignment) [0x00014] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<>c__DisplayClass8_0.<CommonNodesOfElement>b__0 (OmniXaml.Parsers.ProtoParser.AttributeAssignment a) [0x00000] in <filename unknown>:0 
  at System.Linq.Enumerable+WhereSelectEnumerableIterator`2[TSource,TResult].MoveNext () [0x00064] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<CommonNodesOfElement>d__8.MoveNext () [0x001f8] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseElement>d__22.MoveNext () [0x0013c] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseChildren>d__16.MoveNext () [0x00075] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseNestedElements>d__10.MoveNext () [0x00114] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseExpandedElement>d__9.MoveNext () [0x00184] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseElement>d__22.MoveNext () [0x001b2] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseChildren>d__16.MoveNext () [0x00075] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseNestedElements>d__10.MoveNext () [0x00114] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseExpandedElement>d__9.MoveNext () [0x00184] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseElement>d__22.MoveNext () [0x001b2] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseChildren>d__16.MoveNext () [0x00075] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseNestedElements>d__10.MoveNext () [0x00114] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseExpandedElement>d__9.MoveNext () [0x00184] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseElement>d__22.MoveNext () [0x001b2] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseChildren>d__16.MoveNext () [0x00075] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseNestedElements>d__10.MoveNext () [0x00114] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseExpandedElement>d__9.MoveNext () [0x00184] in <filename unknown>:0 
  at OmniXaml.Parsers.ProtoParser.ProtoInstructionParser+<ParseElement>d__22.MoveNext () [0x001b2] in <filename unknown>:0 
  at OmniXaml.Parsers.Parser.InstructionParser.SetNextInstruction () [0x00013] in <filename unknown>:0 
  at OmniXaml.Parsers.Parser.InstructionParser+<ParseMembersOfObject>d__39.MoveNext () [0x00128] in <filename unknown>:0 
  at OmniXaml.Parsers.Parser.InstructionParser+<ParseEmptyElement>d__26.MoveNext () [0x000b1] in <filename unknown>:0 
  at OmniXaml.Parsers.Parser.InstructionParser+<ParseElements>d__24.MoveNext () [0x0013b] in <filename unknown>:0 
  at OmniXaml.Parsers.Parser.InstructionParser+<Pa
woonder wth is that
we are not even using XAML yet
just creating a window from code
Steven Kirk
@grokys
May 10 2016 04:34
the control templates are specified using XAML
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 04:34
hummm
Darnell Williams
@Seeker1437
May 10 2016 04:34
?
Steven Kirk
@grokys
May 10 2016 04:35
have you created an Application class and called RegisterServices on it? https://github.com/Perspex/Perspex/blob/master/src/Perspex.Controls/Application.cs#L186
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 04:35
yep we did
Steven Kirk
@grokys
May 10 2016 04:35
humm
Darnell Williams
@Seeker1437
May 10 2016 04:37
We did not call LoadFromXaml(), did that matter?
Steven Kirk
@grokys
May 10 2016 04:39
yeah i think you need to call that
not sure if that's your problem though
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 04:41
now that we called it
the error changed
Darnell Williams
@Seeker1437
May 10 2016 04:54
okay I guess now App needs to have an Xaml Counterpart?
Steven Kirk
@grokys
May 10 2016 04:57
if you're calling LoadFromXaml on it, then yes :)
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 04:58
if we don't call LoadFromXaml we get that OmniXaml big error I just pasted
Steven Kirk
@grokys
May 10 2016 04:59
tbh you don't need a xaml file/to call LoadFromXaml - you can do everything that's needed in code
the error you're getting without it sounds to me like an assembly isn't being loaded or something
Jason Jarvis
@jazzay
May 10 2016 05:04
Can you see breakpoints in that source file - GetAsset method? That caused me a bit of pain on iOS due to AOT
Since iOS does not dynamically load DLLs I had to hard reference the Theme DLL so it would get included in the AOT. https://github.com/Perspex/Perspex/blob/master/samples/ControlCatalog/MainWindow.xaml.cs
Not sure if this is applicable to your scenario
Jason Jarvis
@jazzay
May 10 2016 05:09
All Xaml files (including the control templates @grokys mentioned) go through the AssetLoader
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 05:15
ok we added the Xaml etc
[02:13:24.954][UNHANDLED EXCEPTION] System.NullReferenceException: Object reference not set to an instance of an object.
  at (wrapper managed-to-native) System.Object:__icall_wrapper_mono_ldvirtfn (object,intptr)
  at Perspex.Threading.Dispatcher.MainLoop (CancellationToken cancellationToken) [0x0000b] in <filename unknown>:0 
  at Perspex.Application.Run (ICloseable closable) [0x00046] in <filename unknown>:0 
  at Perspex.WindowApplicationExtensions.RunWithMainWindow[TWindow] (Perspex.Application app) [0x00011] in <filename unknown>:0 
  at Program.InitUI () [0x00050] in C:\Development\Repos\PI\PI-SDK\PI-SDK\src\PI.SDK.Prolin.Playground\Program.cs:72 
  at Program.Main (System.String[] args) [0x0003b] in C:\Development\Repos\PI\PI-SDK\PI-SDK\src\PI.SDK.Prolin.Playground\Program.cs:44
Darnell Williams
@Seeker1437
May 10 2016 05:18
hmm
wait the MainWindow is embedded right?
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 05:20
EmbeddedResource
as the App.paml
@jazzay not sure if it is related
[02:22:39.317][UNHANDLED EXCEPTION] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> OmniXaml.LoadException: Error loading XAML: OmniXaml.ParseException: The type "{:KeyboardNavigation} cannot be found"
and a whole bunch of OmniXaml stack
Jason Jarvis
@jazzay
May 10 2016 05:56
You are able to build run the ControlCatalog right?
Darnell Williams
@Seeker1437
May 10 2016 10:17
@jazzay in our instance we were trying to use one of the old methods that existed, CreateSimpleWindow() and show that one the screen
The issue we were having is ofc it would crash before we would see anything, we suspected that we might need to make a couple adjustments to the platform too like if we made a mitake or osmehting
Darnell Williams
@Seeker1437
May 10 2016 15:07
@jazzay on iOS return is treated like a space.... that or multiline textbox is not working
Jason Jarvis
@jazzay
May 10 2016 15:13
@Seeker1437 is quite both either is the case. We have not spent any time polishing iOS text input at all. Just got drawing working
Darnell Williams
@Seeker1437
May 10 2016 15:14
Ah gottcha
We will really should see about the virtual window system too haha
@kekekeks had something in the works for that, that way we could have the popups and embedded windows too :(
Jason Jarvis
@jazzay
May 10 2016 15:15
why do we need virtual window system?
ah popups. For mobile not sure embedded windows is a good idea. Popups I can see, and should these use native dialogs in some cases.
Darnell Williams
@Seeker1437
May 10 2016 15:17
It was an idea that your would always have the native window that does the rendering then you could use a virtual system to simulate the multiwindow experience.
Jason Jarvis
@jazzay
May 10 2016 15:17
This will be a large challenge for Perspex figuring out the mobile ergonomics/UX.
We should probably use UWP as the inspiration there and the adaptive UI stuff. Pretty sure they don't allow embedded windows either ;)
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 15:21
@jazzay UWP allow you to put embeeded windows inside their "pop-up"
for instance
even webview windows
login on facebook
you can try Gitter for UWP and see the Github login
it is a popup with a embedded webview
so
for our test here
we are getting:
 System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> OmniXaml.LoadException: Error loading XAML: OmniXaml.ParseException: The type "{:KeyboardNavigation} cannot be found"
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 15:43
and now building ControlCatalog on Perspex source throws this:
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\AutoKeyDictionary.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\DependencySorter.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\EnumExtensions.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\Extensions.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\Guard.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\IAdd.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\IDependency.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\ReflectionExtensions.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\StackingLinkedList.cs' could not be found.
1>CSC : error CS2001: Source file 'C:\Development\Repos\Perspex\src\Markup\Perspex.Markup.Xaml\glass\Glass.Core\StackingLinkedListMixin.cs' could not be found.
Steven Kirk
@grokys
May 10 2016 15:59
@galvesribeiro sounds like you need to do a git submodule update --init
the glass submodule was added recently
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:00
yay!
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:10
ok @jazzay as you asked, I just tried the ControlCatalog sample...
same error
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> OmniXaml.LoadException: Error loading XAML: OmniXaml.ParseException: The type "{:KeyboardNavigation} cannot be found"
@grokys any clue?
Steven Kirk
@grokys
May 10 2016 16:10
is the Perspex.Input assembly loaded at this point?
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:11
yes
it was
Steven Kirk
@grokys
May 10 2016 16:12
hmm, strange - that type should be found then
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:13
blob
danwalmsley
@danwalmsley
May 10 2016 16:14
@galvesribeiro @grokys has to be to do with order of initialization perhaps?
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:14
look at the code on top
that is what we use to initialize
danwalmsley
@danwalmsley
May 10 2016 16:15
move = new App to after the initialize line?
UseSkia, etc
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:15
hum?
Darnell Williams
@Seeker1437
May 10 2016 16:16
yeah it's weird
danwalmsley
@danwalmsley
May 10 2016 16:16
you didn't call RegisterServices()?
Darnell Williams
@Seeker1437
May 10 2016 16:16
it's called in the app ctor
danwalmsley
@danwalmsley
May 10 2016 16:17
ok
Steven Kirk
@grokys
May 10 2016 16:17
i think you need to step into the code starting at PerspexRuntimeTypeSource.GetByPrefix
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:17
well... this app is not inside Perspex source code
I'm using the nightly nugets
danwalmsley
@danwalmsley
May 10 2016 16:18
so your version of ControlCatalog.App
Steven Kirk
@grokys
May 10 2016 16:18
just copy the .dlls and .pdb files from a perspex build into the nuget directory and you can step into perspex
danwalmsley
@danwalmsley
May 10 2016 16:18
does call RegisterServices inside its constructor?
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:18
not my version, the latest one from perspex source @danwalmsley
danwalmsley
@danwalmsley
May 10 2016 16:19
ok then it should be doing
Darnell Williams
@Seeker1437
May 10 2016 16:19
yeah it does
danwalmsley
@danwalmsley
May 10 2016 16:19
ok
Steven Kirk
@grokys
May 10 2016 16:20
i'd advise trying stepping into the working desktop code and also into the not working device code and seeing what the difference is
it's a bit hard to know what's going wrong from afar
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:33
ok...
System.Exception: Could not start timer: IPlatformThreadingInterface is not registered.
we need to implement the render loop by ourselves?
Steven Kirk
@grokys
May 10 2016 16:37
well usually the main loop comes from the underlying platform, e.g. win32, android, ios
you don't have that though
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:37
yeah I don't
Steven Kirk
@grokys
May 10 2016 16:38
so yeah i guess you'll need to implement one
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:38
:(
Darnell Williams
@Seeker1437
May 10 2016 16:38
D: idk how simple that is
XD
Steven Kirk
@grokys
May 10 2016 16:38
not sure
i've never had to do it! it's always been in the OS
probably not too hard for a simple one though
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:39
this is from my old UI stuff
this follow the priciple that we had 1 single STA main thread
and every work item should be posted to that main thread if it needs to update UI
Steven Kirk
@grokys
May 10 2016 16:42
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:42
does that makes sense?
I saw that already Steven
Steven Kirk
@grokys
May 10 2016 16:42
i think so - i think you can use your existing infrastructure
but again, i've never had to implement a main loop
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:42
but there are tons of stuff on win32 which is on the native side
Steven Kirk
@grokys
May 10 2016 16:43
yeah, that's the case for every platform that's been targeted so far
you're the first person to try it without an underlying OS that has a render loop
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:43
yeah, cause they have a windowing/rendering infrastructure hehehe
Darnell Williams
@Seeker1437
May 10 2016 16:43
mhmm
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 16:43
we like hard-mode :P
Steven Kirk
@grokys
May 10 2016 16:43
haha
don't worry about the timer stuff for now
Darnell Williams
@Seeker1437
May 10 2016 16:44
in your synccontext
send is similar to Signal
XD
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 19:33
following the Android sample it should be something like that:
public class PIUIPlatformThreading : IPlatformThreadingInterface
    {
        UISynchronizationContext _syncContext;

        public bool CurrentThreadIsLoopThread => Thread.CurrentThread == _syncContext.CurrentUIThread.Thread;

        public event Action Signaled;

        public void RunLoop(CancellationToken cancellationToken)
        {
            _syncContext = new UISynchronizationContext(cancellationToken);
        }

        public void Signal()
        {
            _syncContext.Post(new SendOrPostCallback(_ => Signaled?.Invoke()), null);
        }

        public IDisposable StartTimer(TimeSpan interval, Action tick)
        {

            if (interval.TotalMilliseconds < 10)
                interval = TimeSpan.FromMilliseconds(10);
            object l = new object();
            var stopped = false;
            Timer timer = null;
            var scheduled = false;
            timer = new Timer(_ =>
            {
                lock (l)
                {
                    if (stopped)
                    {
                        timer.Dispose();
                        return;
                    }
                    if (scheduled)
                        return;
                    scheduled = true;
                    _syncContext.Post(new SendOrPostCallback(z =>
                    {
                        tick();
                        lock (l)
                        {
                            scheduled = false;
                        }
                    }), null);
                }
            }, null, TimeSpan.Zero, interval);

            return Disposable.Create(() =>
            {
                lock (l)
                {
                    stopped = true;
                    timer.Dispose();
                }
            });
        }
    }
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 21:24
@grokys that is not working...
[18:23:44.915][UNHANDLED EXCEPTION] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Call from invalid thread
  at Perspex.Threading.Dispatcher.VerifyAccess () [0x00008] in <filename unknown>:0 
  at Perspex.PerspexObject.VerifyAccess () [0x00005] in <filename unknown>:0 
  at Perspex.PerspexObject.Bind (Perspex.PerspexProperty property, IObservable`1 source, BindingPriority priority) [0x00025] in <filename unknown>:0 
  at Perspex.Styling.Setter.Apply (IStyle style, IStyleable control, IObservable`1 activator) [0x00053] in <filename unknown>:0 
  at Perspex.Styling.Style.Attach (IStyleable control, IStyleHost container) [0x00079] in <filename unknown>:0 
  at Perspex.Markup.Xaml.Styling.StyleInclude.Attach (IStyleable control, IStyleHost container) [0x00014] in <filename unknown>:0 
  at Perspex.Styling.Styles.Attach (IStyleable control, IStyleHost container) [0x0000f] in <filename unknown>:0 
  at Perspex.Markup.Xaml.Styling.StyleInclude.Attach (IStyleable control, IStyleHost container) [0x00014] in <filename unknown>:0 
  at Perspex.Styling.Styles.Attach (IStyleable control, IStyleHost container) [0x0000f] in <filename unknown>:0 
  at Perspex.Styling.Styler.ApplyStyles (IStyleable control, IStyleHost styleHost) [0x0002a] in <filename unknown>:0 
  at Perspex.Styling.Styler.ApplyStyles (IStyleable control, IStyleHost styleHost) [0x0001c] in <filename unknown>:0 
  at Perspex.Styling.Styler.ApplyStyles (IStyleable control) [0x0000a] in <filename unknown>:0 
  at Perspex.Controls.TopLevel..ctor (ITopLevelImpl impl, IPerspexDependencyResolver dependencyResolver) [0x0014c] in <filename unknown>:0 
  at Perspex.Controls.TopLevel..ctor (ITopLevelImpl impl) [0x00007] in <filename unknown>:0 
  at Perspex.Controls.Window..ctor () [0x00011] in <filename unknown>:0 
  at ControlCatalog.MainWindow..ctor () [0x00000] in C:\Development\Repos\Perspex\samples\ControlCatalog\MainWindow.xaml.cs:9 
  at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00019] in <filename unknown>:0 
  at System.RuntimeType.CreateInstanceMono (Boolean nonPublic) [0x000ca] in <filename unknown>:0 
  at System.RuntimeType.CreateInstanceSlow (Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, System.Threading.StackCrawlMark& stackMark) [0x0001a] in <filename unknown>:0 
  at System.RuntimeType.CreateInstanceDefaultCtor (Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, System.Threading.StackCrawlMark& stackMark) [0x0002a] in <filename unknown>:0 
  at System.Activator.CreateInstance[T] () [0x0002d] in <filename unknown>:0 
  at Perspex.WindowApplicationExtensions.RunWithMainWindow[TWindow] (Perspex.Application app) [0x00000] in <filename unknown>:0 
  at Program.InitUI () [0x00050] in C:\Development\Repos\PI\PI-SDK\PI-SDK\src\PI.SDK.Prolin.Playground\Program.cs:72 
  at Program.Main (System.String[] args) [0x0003b] in C:\Development\Repos\PI\PI-SDK\PI-SDK\src\PI.SDK.Prolin.Playground\Program.cs:44
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 22:00
ha...
nice...
there is a PerspexSynchronizationContext which does nothing but forward calls to a Dispatcher which in turns is calling the threading interface... so what is the point of all this? :(
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 22:31
The threading interface acts at a lower level of abstraction than a synchronization context. Your UIThread class would be what you turn into the IPlatformThreadingInterface
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 22:34
@jkoritzinsky are u suggesting me to move the Run() contentent (the while) which pull from the queue the callbackItem insode the IPlatformThreadInterface.RunLoop() ?
and discard my sync context, right?
so the intent of IPlatformThreadInterface is the wrap up a single thread
doesn't need to be a SyncContext implementation, right?
Darnell Williams
@Seeker1437
May 10 2016 22:36
wow THAT MAKES SENSE
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 22:36
Yep. The IPlatformThreadInterface is a platform agnostic wrap of a single thread and the listener point for any OS signalling that happens on the UI thread (which isn’t as relavent for your implementation)
Darnell Williams
@Seeker1437
May 10 2016 22:37
@jkoritzinsky you f___ing rock! I coudln't put my finger on it earlier when I was thinking about ti XD
so I gave up XD
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 22:37
:)
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 22:38
All you should have to do in your implementation is construct a thread and run a while loop that repeatedly calls the Signaled delegate
Darnell Williams
@Seeker1437
May 10 2016 22:39
in which case the thread we contruct is just Thread.CurrentThread correct?
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 22:39
Give me one second to check...
It looks like it doesn’t have to be.
The IPlatformThreadingInterface just has to correctly implement the CurrentThreadIsLoopThread property to return true if everything is happening on the UI thread.
Darnell Williams
@Seeker1437
May 10 2016 22:44

ah okay because I was looking at the window platform,

it basiclly does public static Thread _uiThread;

in the initialize method ii does _uiTHread = Thread.CurrentThread;

then CurrentThreadIsLoopThread => _uiThread == CurrentThread;

Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 22:47
Looks like it’s easiest if it is just the main thread, but it’s not required.
Sounds like we really need to get on beefing up our documentation.
Darnell Williams
@Seeker1437
May 10 2016 22:54
okay x3
yeah IPclPlatformWrapper and IPlatfromThreadingInterface might need renaming too XD
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 22:56
Once I finish up exams I’ll focus my next few PRs on adding more conceptual documentation
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 22:58
@jkoritzinsky what about the StartTimer() ?
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 23:00
Does your underlying OS have a built-in clock that you can reference? If so, you implement StartTimer to start an auto-restarting timer that calls the callback after the specified interval has passed (make sure the callback is on the UI thread though). Otherwise, I’m not too sure.
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 23:02
its a linux
and yes
Threading.Timer is supported there
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 23:03
That should work. Just make sure that you call the callback on the UI Thread. I think you could actually Send or Post the callback call to the SynchronizationContext.
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 23:50
    internal class PIUIPlatformThreading : IPlatformThreadingInterface
    {
        public bool CurrentThreadIsLoopThread => Thread.CurrentThread == _uiThread;

        private BlockingQueue<SendOrPostCallbackItem> _queue = new BlockingQueue<SendOrPostCallbackItem>();
        private ManualResetEvent _stopEvent = new ManualResetEvent(false);
        public event Action Signaled;
        private Thread _uiThread;

        public void RunLoop(CancellationToken cancellationToken)
        {
            _uiThread = new Thread(new ThreadStart(() =>
            {
                while (!cancellationToken.IsCancellationRequested) 
                {
                    bool stop = _stopEvent.WaitOne(0);
                    if (stop)
                    {
                        break;
                    }

                    var workItem = _queue.Dequeue();
                    if (workItem != null)
                    {
                        workItem.Execute();
                        Signaled?.Invoke();
                    }
                }
            }));
            _uiThread.Name = "UI Worker Thread";
            _uiThread.SetApartmentState(ApartmentState.STA);
            _uiThread.Start();
        }

        public void Signal()
        {
            EnsureInvokeOnMainThread(() => Signaled?.Invoke());
        }

        private void EnsureInvokeOnMainThread(Action action) => Post(new SendOrPostCallback(_ => action.Invoke()));

        private void Post(SendOrPostCallback d)
        {
            // queue the item and don't wait for its execution. This is risky because
            // an unhandled exception will terminate the STA thread. Use with caution.
            var item = new SendOrPostCallbackItem(d, null,
                                              ExecutionType.Post);
            _queue.Enqueue(item);
        }

        public IDisposable StartTimer(TimeSpan interval, Action tick)
        {

            if (interval.TotalMilliseconds < 10)
                interval = TimeSpan.FromMilliseconds(10);
            object l = new object();
            var stopped = false;
            Timer timer = null;
            var scheduled = false;
            timer = new Timer(_ =>
            {
                lock (l)
                {
                    if (stopped)
                    {
                        timer.Dispose();
                        return;
                    }
                    if (scheduled)
                        return;
                    scheduled = true;
                    EnsureInvokeOnMainThread(()=>
                    {
                        tick();
                        lock (l)
                        {
                            scheduled = false;
                        }
                    });
                }
            }, null, TimeSpan.Zero, interval);

            return Disposable.Create(() =>
            {
                lock (l)
                {
                    stopped = true;
                    timer.Dispose();
                }
            });
        }
    }
@jkoritzinsky plz have a look at it
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 23:52
At quick glance it looks right.
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 23:54
same thing...
[20:53:38.905][UNHANDLED EXCEPTION] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Call from invalid thread
  at Perspex.Threading.Dispatcher.VerifyAccess () [0x00008] in <filename unknown>:0 
  at Perspex.PerspexObject.VerifyAccess () [0x00005] in <filename unknown>:0 
  at Perspex.PerspexObject.Bind (Perspex.PerspexProperty property, IObservable`1 source, BindingPriority priority) [0x00025] in <filename unknown>:0 
  at Perspex.Styling.Setter.Apply (IStyle style, IStyleable control, IObservable`1 activator) [0x00053] in <filename unknown>:0 
  at Perspex.Styling.Style.Attach (IStyleable control, IStyleHost container) [0x00079] in <filename unknown>:0 
  at Perspex.Markup.Xaml.Styling.StyleInclude.Attach (IStyleable control, IStyleHost container) [0x00014] in <filename unknown>:0 
  at Perspex.Styling.Styles.Attach (IStyleable control, IStyleHost container) [0x0000f] in <filename unknown>:0 
  at Perspex.Markup.Xaml.Styling.StyleInclude.Attach (IStyleable control, IStyleHost container) [0x00014] in <filename unknown>:0 
  at Perspex.Styling.Styles.Attach (IStyleable control, IStyleHost container) [0x0000f] in <filename unknown>:0 
  at Perspex.Styling.Styler.ApplyStyles (IStyleable control, IStyleHost styleHost) [0x0002a] in <filename unknown>:0 
  at Perspex.Styling.Styler.ApplyStyles (IStyleable control, IStyleHost styleHost) [0x0001c] in <filename unknown>:0 
  at Perspex.Styling.Styler.ApplyStyles (IStyleable control) [0x0000a] in <filename unknown>:0 
  at Perspex.Controls.TopLevel..ctor (ITopLevelImpl impl, IPerspexDependencyResolver dependencyResolver) [0x0014c] in <filename unknown>:0 
  at Perspex.Controls.TopLevel..ctor (ITopLevelImpl impl) [0x00007] in <filename unknown>:0 
  at Perspex.Controls.Window..ctor () [0x00011] in <filename unknown>:0 
  at ControlCatalog.MainWindow..ctor () [0x00000] in C:\Development\Repos\Perspex\samples\ControlCatalog\MainWindow.xaml.cs:9 
  at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00019] in <filename unknown>:0 
  at System.RuntimeType.CreateInstanceMono (Boolean nonPublic) [0x000ca] in <filename unknown>:0 
  at System.RuntimeType.CreateInstanceSlow (Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, System.Threading.StackCrawlMark& stackMark) [0x0001a] in <filename unknown>:0 
  at System.RuntimeType.CreateInstanceDefaultCtor (Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, System.Threading.StackCrawlMark& stackMark) [0x0002a] in <filename unknown>:0 
  at System.Activator.CreateInstance[T] () [0x0002d] in <filename unknown>:0 
  at Perspex.WindowApplicationExtensions.RunWithMainWindow[TWindow] (Perspex.Application app) [0x00000] in <filename unknown>:0 
  at Program.InitUI () [0x00050] in C:\Development\Repos\PI\PI-SDK\PI-SDK\src\PI.SDK.Prolin.Playground\Program.cs:72 
  at Program.Main (System.String[] args) [0x0003b] in C:\Development\Repos\PI\PI-SDK\PI-SDK\src\PI.SDK.Prolin.Playground\Program.cs:44
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 23:55
IMaybe the UI has to run on the main thread...
I’m not sure.
Darnell Williams
@Seeker1437
May 10 2016 23:55
that's what I was thinking
Jeremy Koritzinsky
@jkoritzinsky
May 10 2016 23:55
What line is the exception being thrown on?
Darnell Williams
@Seeker1437
May 10 2016 23:56
somewhere during binding actually
Gutemberg Ribeiro
@galvesribeiro
May 10 2016 23:56
have a look on the full exception