Page 1 of 1

Extending Noesis libraries not recognized

Posted: 25 Mar 2014, 05:47
by matt.rudder
Hey guys,

I'm currently trying to implement some custom view models in a C++ sample project I'm working on, but I'm having trouble with the build process. I've got my new BaseComponent subclasses built in a separate shared library from my project, and I copy it to the Bin directory of the SDK so it can be picked up by BuildTool when processing my XAML.

I get the following output from BuildTool when building my XAML:
Ignoring unknown type 'GameModel' (@10,4)
    Parsing DataTemplate (@12,4).
    Unknown type 'Space'
I've referenced the tutorials on Extending Noesis, and forums posts like this one on Class directives (viewtopic.php?f=3&t=84) and I think I've got my shared library set up correctly. Is there documentation anywhere on the file types BuildTool searches for NsRegisterReflection functions to call? I assumed it would search for any file ending in .dylib in the Bin directory on Mac.

Chances are I'm missing something super simple on this. I know you guys are working on this flow for the 1.2 timeframe as well, so if there's a workaround I can use for the time being that would be great as well.

DataModel.h:

#pragma once

#include <Noesis.h>
#include <NsCore/ReflectionImplement.h>
#include <NsCore/BaseComponent.h>
#include <NsCore/ISerializable.h>
#include <NsCore/SerializationData.h>
#include <NsCore/UnserializationData.h>
#include <NsCore/Delegate.h>
#include <NsCore/Symbol.h>
#include <NsCore/String.h>
#include <NsCore/TypeId.h>
#include <NsGui/INotifyPropertyChange.h>

using namespace Noesis::Core;

class DataModel: public Noesis::Core::BaseComponent,
    public Noesis::Gui::INotifyPropertyChange,
    public Noesis::Core::ISerializable
{
public:
    DataModel()
    {
    }

    ~DataModel()
    {
        m_destroyedEvent(this);
    }

    /// From INotifyPropertyChanged
    //@{
    PropertyChangedEvent& PropertyChanged()
    {
        return m_changedEvent;
    }

    DestroyedDelegate& Destroyed()
    {
        return m_destroyedEvent;
    }
    //@}

    /// From ISerializable
    //@{
    NsUInt32 GetVersion() const
    {
        return 0;
    }

    void Serialize(Noesis::Core::SerializationData* data) const
    {
    }

    void Unserialize(Noesis::Core::UnserializationData* data, NsUInt32 version)
    {
    }

    void PostUnserialize()
    {
    }
    //@}

protected:
    virtual void OnPropertyChanged(NsSymbol propName)
    {
        m_changedEvent(this, propName);
    }

private:
    PropertyChangedEvent m_changedEvent;
    DestroyedDelegate m_destroyedEvent;

    NS_IMPLEMENT_INLINE_REFLECTION(DataModel, BaseComponent)
    {
      NsMeta<TypeId>("DataModel");
      NsImpl<INotifyPropertyChange>();
      NsImpl<ISerializable>();
    }
};
GameModel.h:

#pragma once

#include "DataModel.h"
#include "Space.h"
#include <NsGui/Collection.h>

using namespace Noesis::Core;
using namespace Noesis::Gui;

class GameModel : public DataModel
{
public:
    GameModel()
    {
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());

      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());

      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());

      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
      m_spaces.Add(new Space());
    }

    ~GameModel()
    {
    }

    const Collection* GetSpaces() const
    {
      return &m_spaces;
    }

    /// From ISerializable
    //@{
    void Serialize(Noesis::Core::SerializationData* data) const
    {

    }

    void Unserialize(Noesis::Core::UnserializationData* data, NsUInt32 version)
    {

    }
    //@}


private:
    Noesis::Gui::Collection m_spaces;

    NS_IMPLEMENT_INLINE_REFLECTION(GameModel, DataModel)
    {
      NsMeta<TypeId>("GameModel");

      NsProp("Spaces", &GameModel::GetSpaces);
    }
};
NsRegister.cpp:
#include "GameModel.h"
#include "Space.h"

#include <NsCore/ReflectionImplement.h>
#include <NsCore/Package.h>
#include <NsCore/LoggerMacros.h>

using namespace Noesis::Core;

extern "C" NS_DLL_EXPORT
void NsRegisterReflection(ComponentFactory* factory, NsBool registerComponents)
{
  NS_REGISTER_COMPONENT(GameModel)
  NS_REGISTER_COMPONENT(Space)
}
Space.h:

#pragma once

#include "GameModel.h"

using namespace Noesis::Core;

class Space : public DataModel
{
public:
  Space()
  {

  }

private:
  NS_IMPLEMENT_INLINE_REFLECTION(Space, DataModel)
  {
    NsMeta<TypeId>("Space");
  }
};
MainWindow.xaml:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d"
  DataContext="{StaticResource ViewModel}"
  Background="#FFD4D4D4">
  <Grid.Resources>
    <GameModel x:Key="ViewModel" />

    <DataTemplate x:Key="{x:Type Space}">
      <Grid>
        <TextBlock>0</TextBlock>
      </Grid>
    </DataTemplate>
  </Grid.Resources>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
  </Grid.RowDefinitions>

  <ItemsControl ItemsSource="{Binding Spaces}">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <Grid />
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
  </ItemsControl>
</Grid>

Re: Extending Noesis libraries not recognized

Posted: 26 Mar 2014, 00:09
by jsantos
Hi Matt,

There is a bug in the part that loads the dynamic libraries because it is using the extension .so in OSX although it should be using .dylib as you are expecting.

Will be fixed in the next version (1.1.6) to be released in a few days.

Thanks for the feedback.