--- /dev/null
+{
+ "variables": {
+ 'DALI_JS_DIR%':'../plugins/dali-script-v8/src/'
+ },
+ "targets": [
+ {
+ 'target_name': 'dali',
+ 'include_dirs': ['<(DALI_JS_DIR)/',
+ '<(DALI_JS_DIR)/utils'],
+ 'sources': [ 'dali-addon.cpp',
+ 'javascript-application-options.cpp',
+ '<(DALI_JS_DIR)/utils/v8-utils.cpp',
+ '<(DALI_JS_DIR)/dali-wrapper.cpp',
+ '<(DALI_JS_DIR)/shared/base-wrapped-object.cpp',
+ '<(DALI_JS_DIR)/shared/object-template-helper.cpp',
+ '<(DALI_JS_DIR)/actors/actor-wrapper.cpp',
+ '<(DALI_JS_DIR)/actors/actor-api.cpp',
+ '<(DALI_JS_DIR)/actors/layer-api.cpp',
+ '<(DALI_JS_DIR)/actors/image-actor-api.cpp',
+ '<(DALI_JS_DIR)/actors/camera-actor-api.cpp',
+ '<(DALI_JS_DIR)/constants/constants-wrapper.cpp',
+ '<(DALI_JS_DIR)/animation/animation-api.cpp',
+ '<(DALI_JS_DIR)/animation/animation-wrapper.cpp',
+ '<(DALI_JS_DIR)/animation/constrainer-api.cpp',
+ '<(DALI_JS_DIR)/animation/linear-constrainer-wrapper.cpp',
+ '<(DALI_JS_DIR)/animation/path-api.cpp',
+ '<(DALI_JS_DIR)/animation/path-constrainer-wrapper.cpp',
+ '<(DALI_JS_DIR)/animation/path-wrapper.cpp',
+ '<(DALI_JS_DIR)/stage/stage-wrapper.cpp',
+ '<(DALI_JS_DIR)/events/event-object-generator.cpp',
+ '<(DALI_JS_DIR)/events/pan-gesture-detector-api.cpp',
+ '<(DALI_JS_DIR)/events/pan-gesture-detector-wrapper.cpp',
+ '<(DALI_JS_DIR)/stage/stage-api.cpp',
+ '<(DALI_JS_DIR)/shader-effects/shader-effect-api.cpp',
+ '<(DALI_JS_DIR)/shader-effects/shader-effect-wrapper.cpp',
+ '<(DALI_JS_DIR)/image/image-wrapper.cpp',
+ '<(DALI_JS_DIR)/image/image-api.cpp',
+ '<(DALI_JS_DIR)/image/buffer-image-api.cpp',
+ '<(DALI_JS_DIR)/image/native-image-api.cpp',
+ '<(DALI_JS_DIR)/image/frame-buffer-image-api.cpp',
+ '<(DALI_JS_DIR)/image/resource-image-api.cpp',
+ '<(DALI_JS_DIR)/image/nine-patch-image-api.cpp',
+ '<(DALI_JS_DIR)/object/handle-wrapper.cpp',
+ '<(DALI_JS_DIR)/object/property-value-wrapper.cpp',
+ '<(DALI_JS_DIR)/signals/signal-manager.cpp',
+ '<(DALI_JS_DIR)/render-tasks/render-task-list-api.cpp',
+ '<(DALI_JS_DIR)/render-tasks/render-task-list-wrapper.cpp',
+ '<(DALI_JS_DIR)/render-tasks/render-task-api.cpp',
+ '<(DALI_JS_DIR)/render-tasks/render-task-wrapper.cpp',
+ '<(DALI_JS_DIR)/toolkit/builder/builder-api.cpp',
+ '<(DALI_JS_DIR)/toolkit/builder/builder-wrapper.cpp',
+ '<(DALI_JS_DIR)/toolkit/focus-manager/keyboard-focus-manager-api.cpp',
+ '<(DALI_JS_DIR)/toolkit/focus-manager/keyboard-focus-manager-wrapper.cpp',
+ '<(DALI_JS_DIR)/signals/dali-any-javascript-converter.cpp',
+ '<(DALI_JS_DIR)/garbage-collector/garbage-collector.cpp',
+ '<(DALI_JS_DIR)/module-loader/module.cpp',
+ '<(DALI_JS_DIR)/module-loader/module-loader.cpp'
+ ],
+ 'cflags': [
+ '-fPIC',
+ '-frtti',
+ '<!@(pkg-config --cflags dali dali-toolkit)'
+ ],
+
+ 'cflags_cc': [
+ '-fexceptions', # Enable exception handler
+ '-frtti' # needed for typeinfo with dali-any
+ ],
+ 'ldflags': [
+ '<!@(pkg-config --libs-only-L --libs-only-other dali dali-toolkit)'
+ ],
+ 'libraries': [
+ '<!@(pkg-config --libs-only-l dali dali-toolkit)'
+ ]
+ }]
+}
--- /dev/null
+# This file is generated by gyp; do not edit.
+
+export builddir_name ?= ./build/.
+.PHONY: all
+all:
+ $(MAKE) dali
--- /dev/null
+# Do not edit. File was generated by node-gyp's "configure" step
+{
+ "target_defaults": {
+ "cflags": [],
+ "default_configuration": "Release",
+ "defines": [],
+ "include_dirs": [],
+ "libraries": []
+ },
+ "variables": {
+ "clang": 0,
+ "gcc_version": 46,
+ "host_arch": "x64",
+ "icu_small": "false",
+ "node_install_npm": "true",
+ "node_prefix": "",
+ "node_shared_cares": "false",
+ "node_shared_http_parser": "false",
+ "node_shared_libuv": "false",
+ "node_shared_openssl": "false",
+ "node_shared_v8": "false",
+ "node_shared_zlib": "false",
+ "node_tag": "",
+ "node_use_dtrace": "false",
+ "node_use_etw": "false",
+ "node_use_mdb": "false",
+ "node_use_openssl": "true",
+ "node_use_perfctr": "false",
+ "openssl_no_asm": 0,
+ "python": "/usr/bin/python",
+ "target_arch": "x64",
+ "uv_library": "static_library",
+ "uv_parent_path": "/deps/uv/",
+ "uv_use_dtrace": "false",
+ "v8_enable_gdbjit": 0,
+ "v8_enable_i18n_support": 0,
+ "v8_no_strict_aliasing": 1,
+ "v8_optimized_debug": 0,
+ "v8_random_seed": 0,
+ "v8_use_snapshot": "true",
+ "want_separate_host_toolset": 0,
+ "nodedir": "/home/likewise-open/SERILOCAL/nick.holland/.node-gyp/0.12.4",
+ "copy_dev_lib": "true",
+ "standalone_static_library": 1
+ }
+}
--- /dev/null
+# This file is generated by gyp; do not edit.
+
+TOOLSET := target
+TARGET := dali
+DEFS_Debug := \
+ '-DNODE_GYP_MODULE_NAME=dali' \
+ '-D_LARGEFILE_SOURCE' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DBUILDING_NODE_EXTENSION' \
+ '-DDEBUG' \
+ '-D_DEBUG'
+
+# Flags passed to all source files.
+CFLAGS_Debug := \
+ -fPIC \
+ -pthread \
+ -Wall \
+ -Wextra \
+ -Wno-unused-parameter \
+ -m64 \
+ -fPIC \
+ -frtti \
+ -I/home/likewise-open/SERILOCAL/nick.holland/dali-env/opt/include/dali \
+ -I/home/likewise-open/SERILOCAL/nick.holland/dali-env/opt/include \
+ -g \
+ -O0
+
+# Flags passed to only C files.
+CFLAGS_C_Debug :=
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Debug := \
+ -fno-rtti \
+ -fno-exceptions \
+ -fexceptions \
+ -frtti
+
+INCS_Debug := \
+ -I/home/likewise-open/SERILOCAL/nick.holland/.node-gyp/0.12.4/src \
+ -I/home/likewise-open/SERILOCAL/nick.holland/.node-gyp/0.12.4/deps/uv/include \
+ -I/home/likewise-open/SERILOCAL/nick.holland/.node-gyp/0.12.4/deps/v8/include \
+ -I$(srcdir)/../plugins/dali-script-v8/src \
+ -I$(srcdir)/../plugins/dali-script-v8/src/utils
+
+DEFS_Release := \
+ '-DNODE_GYP_MODULE_NAME=dali' \
+ '-D_LARGEFILE_SOURCE' \
+ '-D_FILE_OFFSET_BITS=64' \
+ '-DBUILDING_NODE_EXTENSION'
+
+# Flags passed to all source files.
+CFLAGS_Release := \
+ -fPIC \
+ -pthread \
+ -Wall \
+ -Wextra \
+ -Wno-unused-parameter \
+ -m64 \
+ -fPIC \
+ -frtti \
+ -I/home/likewise-open/SERILOCAL/nick.holland/dali-env/opt/include/dali \
+ -I/home/likewise-open/SERILOCAL/nick.holland/dali-env/opt/include \
+ -O3 \
+ -ffunction-sections \
+ -fdata-sections \
+ -fno-tree-vrp \
+ -fno-omit-frame-pointer
+
+# Flags passed to only C files.
+CFLAGS_C_Release :=
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Release := \
+ -fno-rtti \
+ -fno-exceptions \
+ -fexceptions \
+ -frtti
+
+INCS_Release := \
+ -I/home/likewise-open/SERILOCAL/nick.holland/.node-gyp/0.12.4/src \
+ -I/home/likewise-open/SERILOCAL/nick.holland/.node-gyp/0.12.4/deps/uv/include \
+ -I/home/likewise-open/SERILOCAL/nick.holland/.node-gyp/0.12.4/deps/v8/include \
+ -I$(srcdir)/../plugins/dali-script-v8/src \
+ -I$(srcdir)/../plugins/dali-script-v8/src/utils
+
+OBJS := \
+ $(obj).target/$(TARGET)/dali-addon.o \
+ $(obj).target/$(TARGET)/javascript-application-options.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/utils/v8-utils.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/dali-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/shared/base-wrapped-object.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/shared/object-template-helper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/actors/actor-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/actors/actor-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/actors/layer-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/actors/image-actor-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/actors/camera-actor-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/constants/constants-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/animation/animation-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/animation/animation-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/animation/constrainer-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/animation/linear-constrainer-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/animation/path-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/animation/path-constrainer-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/animation/path-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/stage/stage-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/events/event-object-generator.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/events/pan-gesture-detector-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/events/pan-gesture-detector-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/stage/stage-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/shader-effects/shader-effect-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/shader-effects/shader-effect-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/image/image-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/image/image-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/image/buffer-image-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/image/native-image-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/image/frame-buffer-image-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/image/resource-image-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/image/nine-patch-image-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/object/handle-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/object/property-value-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/signals/signal-manager.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/render-tasks/render-task-list-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/render-tasks/render-task-list-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/render-tasks/render-task-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/render-tasks/render-task-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/toolkit/builder/builder-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/toolkit/builder/builder-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/toolkit/focus-manager/keyboard-focus-manager-api.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/toolkit/focus-manager/keyboard-focus-manager-wrapper.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/signals/dali-any-javascript-converter.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/garbage-collector/garbage-collector.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/module-loader/module.o \
+ $(obj).target/$(TARGET)/../plugins/dali-script-v8/src/module-loader/module-loader.o
+
+# Add to the list of files we specially track dependencies for.
+all_deps += $(OBJS)
+
+# CFLAGS et al overrides must be target-local.
+# See "Target-specific Variable Values" in the GNU Make manual.
+$(OBJS): TOOLSET := $(TOOLSET)
+$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
+$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
+
+# Suffix rules, putting all outputs into $(obj).
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
+ @$(call do_cmd,cxx,1)
+
+# Try building from generated source, too.
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
+ @$(call do_cmd,cxx,1)
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
+ @$(call do_cmd,cxx,1)
+
+# End of this set of suffix rules
+### Rules for final target.
+LDFLAGS_Debug := \
+ -pthread \
+ -rdynamic \
+ -m64 \
+ -L/home/likewise-open/SERILOCAL/nick.holland/dali-env/opt/lib
+
+LDFLAGS_Release := \
+ -pthread \
+ -rdynamic \
+ -m64 \
+ -L/home/likewise-open/SERILOCAL/nick.holland/dali-env/opt/lib
+
+LIBS := \
+ -ldali-adaptor \
+ -ldali-toolkit \
+ -ldali-core
+
+$(obj).target/dali.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
+$(obj).target/dali.node: LIBS := $(LIBS)
+$(obj).target/dali.node: TOOLSET := $(TOOLSET)
+$(obj).target/dali.node: $(OBJS) FORCE_DO_CMD
+ $(call do_cmd,solink_module)
+
+all_deps += $(obj).target/dali.node
+# Add target alias
+.PHONY: dali
+dali: $(builddir)/dali.node
+
+# Copy this to the executable output path.
+$(builddir)/dali.node: TOOLSET := $(TOOLSET)
+$(builddir)/dali.node: $(obj).target/dali.node FORCE_DO_CMD
+ $(call do_cmd,copy)
+
+all_deps += $(builddir)/dali.node
+# Short alias for building this executable.
+.PHONY: dali.node
+dali.node: $(obj).target/dali.node $(builddir)/dali.node
+
+# Add executable to "all" target.
+.PHONY: all
+all: $(builddir)/dali.node
+
--- /dev/null
+/* Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <node.h>
+#include <public-api/dali-core.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <integration-api/core.h>
+#include <integration-api/adaptors/adaptor.h>
+#include <public-api/adaptor-framework/window.h>
+#include <devel-api/adaptor-framework/singleton-service.h>
+
+// INTERNAL INCLUDES
+#include <dali-wrapper.h>
+#include "javascript-application-options.h"
+
+using namespace Dali;
+
+namespace DaliNodeAddon
+{
+
+class DaliApplication
+{
+public:
+
+ DaliApplication()
+ : mInitialized( false),
+ mSingletonService(SingletonService::New()),
+ mAdaptor( NULL )
+ {
+ }
+
+ ~DaliApplication()
+ {
+ mSingletonService.UnregisterAll();
+ delete mAdaptor;
+ mWindow.Reset();
+ }
+
+ bool Initialized() const
+ {
+ return mInitialized;
+ }
+
+ void Initialize( ApplicationOptions options )
+ {
+ if( mInitialized )
+ {
+ return;
+ }
+
+ // 1. Create the window ( adaptor requires a window)
+ const WindowOptions& window( options.window);
+
+ mWindow = Window::New( window.positionSize, window.name, window.transparent );
+
+ // 2. create the adaptor
+ Adaptor* adaptor = &Adaptor::New( mWindow );
+
+ // 3. start the adaptor
+ adaptor->Start();
+
+ // Set the view modes
+
+ if( options.stereo.viewMode > Dali::MONO )
+ {
+ adaptor->SetStereoBase( options.stereo.stereoBase );
+ adaptor->SetViewMode( options.stereo.viewMode );
+ }
+
+ // fire the scene create signal
+ adaptor->SceneCreated();
+
+ mInitialized = true;
+ }
+private:
+
+ bool mInitialized;
+ SingletonService mSingletonService;
+ Adaptor* mAdaptor;
+ Window mWindow;
+
+};
+
+DaliApplication app;
+
+void CreateDali(const v8::FunctionCallbackInfo<v8::Value>& args)
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ ApplicationOptions options;
+
+ bool ok = GetApplicationOptions( args, options);
+ if (!ok )
+ {
+ isolate->ThrowException( v8::Exception::TypeError( v8::String::NewFromUtf8(isolate, "Please check arguments passed to DALi require") ) );
+ return;
+ }
+
+ app.Initialize( options );
+
+ // the return value from calling the function require('dali.js)( options )
+ // is the dali object
+ args.GetReturnValue().Set( V8Plugin::DaliWrapper::CreateWrapperForNodeJS( isolate ) );
+}
+
+
+/**
+ * We make module.exports a function so that the developer can pass to
+ * parameters to DALi when it's 'required'
+ * E.g
+ *
+ *
+ * var window= {
+ * x:10,
+ * y:10,
+ * width:800,
+ * height: 600,
+ * transparent: false,
+ * name:'my-first-dali-app'
+ * };
+ *
+ * var viewMode {
+ * 'stereoscopic-mode':'stereo-vertical', // mono, stereo-horizontal, stereo-vertical, stereo-interlaced,
+ * 'stereo-base': 65 // Distance in millimeters between left/right cameras typically between (50-70mm)
+ * };
+ *
+ * var options= {
+ * 'window': window,
+ * 'view-mode': viewMode,
+ * 'style-sheet': 'my-theme.json'
+ * }
+ *
+ * var dali = require('dali.js')( options )
+ *
+ *
+ */
+void ExportDaliModule(v8::Handle<v8::Object> exports, v8::Handle<v8::Object> module)
+{
+ NODE_SET_METHOD(module, "exports", CreateDali);
+}
+
+} // namespace DaliNodeAddon
+
+NODE_MODULE(dali, DaliNodeAddon::ExportDaliModule)
+
+
+
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// HEADER
+#include "javascript-application-options.h"
+
+// EXTERNAL INCLUDES
+#include <cstring>
+
+// INTERNAL INCLUDES
+#include <v8-utils.h>
+
+namespace DaliNodeAddon
+{
+
+namespace
+{
+
+struct StereoInfo
+{
+ const char* const name;
+ Dali::ViewMode mode;
+};
+StereoInfo StereoModeTable[] = {
+ { "mono", Dali::MONO},
+ { "stereo-horizontal", Dali::STEREO_HORIZONTAL },
+ { "stereo-vertical", Dali::STEREO_VERTICAL },
+ { "stereo-interlaced", Dali::STEREO_INTERLACED },
+};
+
+const unsigned int numberViewModes = sizeof( StereoModeTable ) / sizeof( StereoModeTable[0] );
+
+bool GetViewMode( const std::string& modeString, Dali::ViewMode& mode )
+{
+ for( unsigned int i = 0; i < numberViewModes; ++i )
+ {
+ const StereoInfo& info (StereoModeTable[i]);
+
+ if( strcmp ( modeString.c_str() , info.name ) == 0 )
+ {
+ mode = info.mode;
+ return true;
+ }
+ }
+ // mode not found
+ mode = Dali::MONO;
+ return false;
+}
+
+
+// Note we can't parse the enviroment options for window width / height because
+// adaptor which holds the environment option class has not been created
+// and we can't create it, until we have a window
+bool ParseWindowOptions( v8::Isolate* isolate, const v8::Local<v8::Object>& obj, WindowOptions& window )
+{
+ v8::HandleScope scope(isolate);
+
+ v8::Local<v8::Value> xValue = obj->Get( v8::String::NewFromUtf8( isolate, "x" ) );
+ v8::Local<v8::Value> yValue = obj->Get( v8::String::NewFromUtf8( isolate, "y" ) );
+ v8::Local<v8::Value> widthValue = obj->Get( v8::String::NewFromUtf8( isolate, "width" ) );
+ v8::Local<v8::Value> heightValue = obj->Get( v8::String::NewFromUtf8( isolate, "height" ) );
+ v8::Local<v8::Value> nameValue = obj->Get( v8::String::NewFromUtf8( isolate, "name" ) );
+ v8::Local<v8::Value> transparencyValue = obj->Get( v8::String::NewFromUtf8( isolate, "transparent" ) );
+
+ // if x,y are optional
+ if( xValue->IsUint32() )
+ {
+ window.positionSize.x = xValue->ToUint32()->Value();
+ }
+ if( yValue->IsUint32() )
+ {
+ window.positionSize.y = yValue->ToUint32()->Value();
+ }
+
+ // width and height are optional but will only accept them if they are both set
+ if( widthValue->IsUint32() && heightValue->IsUint32() )
+ {
+ window.positionSize.width = widthValue->ToUint32()->Value();
+ window.positionSize.height = heightValue->ToUint32()->Value();
+ }
+
+ // get the window name
+ if( nameValue->IsString() )
+ {
+ window.name = Dali::V8Plugin::V8Utils::v8StringToStdString( nameValue );
+ }
+ else
+ {
+ window.name ="DALi application";
+ }
+
+ if( transparencyValue->IsBoolean() )
+ {
+ window.transparent = transparencyValue->ToBoolean()->Value();
+ }
+ return true;
+}
+
+bool ParseStereoScopicOptions( v8::Isolate* isolate, const v8::Local<v8::Object>& stereoObject, StereoScopicOptions& options )
+{
+ v8::HandleScope scope(isolate);
+
+ v8::Local<v8::Value> modeValue = stereoObject->Get( v8::String::NewFromUtf8( isolate, "stereoscopic-mode" ) );
+ v8::Local<v8::Value> stereoBaseValue = stereoObject->Get( v8::String::NewFromUtf8( isolate, "stereo-base" ) );
+
+ if( !modeValue->IsString() )
+ {
+ return true;
+ }
+
+ std::string mode = Dali::V8Plugin::V8Utils::v8StringToStdString( modeValue );
+ bool ok = GetViewMode( mode, options.viewMode);
+ if( !ok )
+ {
+ return false;
+ }
+ if( stereoBaseValue->IsNumber() )
+ {
+ options.stereoBase = stereoBaseValue->ToNumber()->Value();
+ }
+
+ return true;
+}
+
+} // unnamed namespace
+
+bool GetApplicationOptions(const v8::FunctionCallbackInfo<v8::Value>& args, ApplicationOptions& options )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope scope(isolate);
+ bool ok( false );
+
+ if( !args[ 0 ]->IsObject() )
+ {
+ return false;
+ }
+
+ v8::Local<v8::Object> object = args[ 0 ]->ToObject();
+
+ // get the window settings
+ v8::Local<v8::Value> windowValue= object->Get( v8::String::NewFromUtf8( isolate, "window" ) );
+ if( windowValue->IsObject() )
+ {
+ ok = ParseWindowOptions( isolate, windowValue->ToObject(), options.window );
+ if( !ok )
+ {
+ return false; // missing window size
+ }
+ }
+
+ // get the stereoscopic settings
+ v8::Local<v8::Value> stereoValue= object->Get( v8::String::NewFromUtf8( isolate, "view-mode" ) );
+ if( stereoValue->IsObject() )
+ {
+ ok = ParseStereoScopicOptions( isolate, stereoValue->ToObject(), options.stereo );
+ if( !ok )
+ {
+ return false; // incorrect stereoscopic mode
+ }
+ }
+
+ // get the style sheet
+ v8::Local<v8::Value> stylesheetValue= object->Get( v8::String::NewFromUtf8( isolate, "style-sheet" ) );
+ if( stylesheetValue->IsString() )
+ {
+ options.stylesheet = Dali::V8Plugin::V8Utils::v8StringToStdString( stylesheetValue );
+ }
+
+ return true;
+}
+
+} // namespace DaliNodeAddon
--- /dev/null
+#ifndef __DALI_JAVASCRIPT_APPLICATION_OPTIONS_H__
+#define __DALI_JAVASCRIPT_APPLICATION_OPTIONS_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <public-api/dali-core.h>
+#include <public-api/adaptor-framework/window.h>
+#include <v8.h>
+
+namespace DaliNodeAddon
+{
+
+struct WindowOptions
+{
+ WindowOptions()
+ : positionSize(0,0,0,0)
+ {
+ }
+
+ std::string name;
+ Dali::PositionSize positionSize;
+ bool transparent:1;
+};
+
+struct StereoScopicOptions
+{
+ StereoScopicOptions()
+ : viewMode(Dali::MONO),
+ stereoBase(65.f)
+ {
+ }
+
+ Dali::ViewMode viewMode;
+ float stereoBase;
+};
+
+struct ApplicationOptions
+{
+ WindowOptions window;
+ StereoScopicOptions stereo;
+ std::string stylesheet;
+};
+
+/**
+ * @brief parse the dali JavaScript application options
+ * The options are passed to dali when require is called.
+ * E.g. var dali.require('dali.js)( {options object} )
+ *
+ * @param[in] args JavaScript arguments
+ * @param[out] options assigned Dali options
+ * @return true on success, false on failure
+ *
+ */
+bool GetApplicationOptions( const v8::FunctionCallbackInfo<v8::Value>& args, ApplicationOptions& options );
+
+
+} // namespace DaliNodeAddon
+
+
+
+#endif // __DALI_JAVASCRIPT_APPLICATION_OPTIONS_H__
--- /dev/null
+{
+ "name": "dali",
+ "version": "0.0.0",
+ "description": "DALi 3D Engine addon",
+ "main": "index.js",
+ "gypfile": "true",
+ "scripts": {
+ "preinstall" : "./configure",
+ "install" : "make && make install",
+ "test" : "node test.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "review.tizen.org:29418/platform/core/uifw/dali-core"
+ },
+ "keywords": [
+ "dali",
+ "3D",
+ "engine",
+ "OpenGL",
+ "user interface"
+ ],
+ "author": "Samsung",
+ "license": "http://www.apache.org/licenses/LICENSE-2.0"
+}
--- /dev/null
+ var window= {
+ x:800,
+ y:500,
+ width:880,
+ height: 1020,
+ transparent: false,
+ name:'my-first-dali-app'
+ };
+var viewMode={
+ 'stereoscopic-mode':'mono', // stereo-horizontal, stereo-vertical, stereo-interlaced,
+ 'stereo-base': 65 // Distance in millimeters between left/right cameras typically between (50-70mm)
+ };
+ var options= {
+ 'window': window,
+ 'view-mode': viewMode,
+ }
+
+var dali = require('./build/Release/dali')( options );
+var netflixRoulette = require('netflix-roulette');
+
+
+var NUMBER_OF_IMAGES = 40; // for now use 16 ( demo files go up to 30)
+var DEMO_IMAGES = []; // array to store Dali Images
+var VIDEO_WALL_ACTORS = []; // array to store Image actors
+var VIDEO_WALL_ROWS = 5; // use 3 rows for the video wall
+var VIDEO_WALL_COLUMNS = 6; // use 12 columns for the video wall
+var VIDEO_WALL_TOTAL_ITEMS = VIDEO_WALL_COLUMNS * VIDEO_WALL_ROWS; // total items
+var VIDEO_WALL_ITEM_SIZE = 128; // width / height of a item in the video wall
+var BORDER_SIZE = 5;
+var VIDEO_WALL_ITEM_SIZE_NO_BORDER = VIDEO_WALL_ITEM_SIZE - BORDER_SIZE;
+var VIDEO_WALL_WIDTH = VIDEO_WALL_COLUMNS * VIDEO_WALL_ITEM_SIZE;
+var VIDEO_WALL_HEIGHT = VIDEO_WALL_ROWS * VIDEO_WALL_ITEM_SIZE;
+var daliApp = {};
+var posters = [];
+
+var wallRootActor; // the root actor of the video wall
+
+
+daliApp.loadNetflixImages = function() {
+
+ if( NUMBER_OF_IMAGES >= VIDEO_WALL_TOTAL_ITEMS)
+ {
+ NUMBER_OF_IMAGES = VIDEO_WALL_TOTAL_ITEMS-1;
+ }
+
+ for (index = 0; index < NUMBER_OF_IMAGES; ++index) {
+
+ fileName = posters[ index % (posters.length-1) ];
+ if ( fileName )
+ {
+ DEMO_IMAGES[index] = new dali.ResourceImage( { url:fileName } );
+ }
+ }
+}
+
+
+daliApp.createRootActor = function() {
+ wallRootActor = new dali.Actor();
+ wallRootActor.parentOrigin = dali.CENTER;
+ wallRootActor.anchorPoint = dali.CENTER;
+ dali.stage.add(wallRootActor);
+
+ var field = new dali.Control("TextField");
+ field.parentOrigin = dali.CENTER;
+ field.anchorPoint = dali.CENTER;
+
+ field.placeholderText = "DALi netflix netflix-roulette demo";
+ dali.stage.add( field );
+}
+
+
+
+daliApp.getWallActorIndex = function(x, y) {
+ return x + y * VIDEO_WALL_COLUMNS;
+}
+
+daliApp.createActors = function() {
+ daliApp.createRootActor();
+
+ var anim = new dali.Animation(1);
+ var animOptions = {
+ alpha: "linear",
+ delay: 0.0, // used to delay the start of the animation
+ duration: 1, // duration of the animation
+ };
+
+ for (y = 0; y < VIDEO_WALL_ROWS; ++y) {
+ for (x = 0; x < VIDEO_WALL_COLUMNS; ++x) {
+
+ var actorIndex = daliApp.getWallActorIndex(x, y);
+ var imageActor = new dali.ImageActor();
+
+ // wrap image index between 0 and NUMBER_OF_IMAGES
+ var imageIndex = actorIndex % NUMBER_OF_IMAGES;
+
+ imageActor.setImage(DEMO_IMAGES[imageIndex]);
+
+ imageActor.parentOrigin = dali.CENTER;
+ imageActor.anchorPoint = dali.CENTER;
+ imageActor.size = [VIDEO_WALL_ITEM_SIZE_NO_BORDER, VIDEO_WALL_ITEM_SIZE_NO_BORDER, 1.0]; // start with zero size so it zooms up
+
+ var xPosition = x * VIDEO_WALL_ITEM_SIZE;
+ // as the middle the wall is at zero (relative to wallRootActor), we need to subtract half the wall width.
+ // + add half item size because the item anchor point is the center of the wallRootActor.
+ xPosition = xPosition - (VIDEO_WALL_WIDTH / 2) + (VIDEO_WALL_ITEM_SIZE / 2);
+
+ var yPosition = y * VIDEO_WALL_ITEM_SIZE;
+ yPosition = yPosition - (VIDEO_WALL_HEIGHT / 2) + (VIDEO_WALL_ITEM_SIZE / 2);
+
+ imageActor.position = [0,0,0];
+
+ animOptions.delay+=0.25;
+ anim.animateTo( imageActor,"position",[xPosition, yPosition, 0.0],animOptions);
+ // store the actor
+ VIDEO_WALL_ACTORS[actorIndex] = imageActor;
+
+ // Add to the video wall root actor.
+ wallRootActor.add(imageActor);
+ }
+ }
+ anim.play();
+}
+
+function Initialise() {
+
+ daliApp.loadNetflixImages();
+
+ daliApp.createActors();
+}
+
+function actorLoaded( error, data )
+{
+ for( i = 0; i < data.length; ++i )
+ {
+ var entry = data[i];
+
+ if( entry.poster )
+ {
+ posters.push(entry.poster);
+ //console.log(" entry = " + entry.poster );
+ }
+ }
+ Initialise();
+
+}
+
+
+netflixRoulette.actor('nicolas', actorLoaded );
+
v8::Persistent<v8::ObjectTemplate> ActorWrapper::mImageActorTemplate;
v8::Persistent<v8::ObjectTemplate> ActorWrapper::mCameraActorTemplate;
v8::Persistent<v8::ObjectTemplate> ActorWrapper::mLayerActorTemplate;
-v8::Persistent<v8::ObjectTemplate> ActorWrapper::mTextLabelTemplate;
namespace
{
{ &ActorWrapper::mActorTemplate }, // ACTOR
{ &ActorWrapper::mImageActorTemplate }, // IMAGE_ACTOR
{ &ActorWrapper::mLayerActorTemplate }, // LAYER_ACTOR
- { &ActorWrapper::mCameraActorTemplate}, // CAMERA_ACTOR
- { &ActorWrapper::mTextLabelTemplate }
+ { &ActorWrapper::mCameraActorTemplate} // CAMERA_ACTOR
};
/**
/**
* Lookup table to match a actor type with a constructor and supported API's.
+ * HandleWrapper::ActorType is used to index this table
*/
const ActorApiStruct ActorApiLookup[]=
{
{"ImageActor", ActorWrapper::IMAGE_ACTOR, ImageActorApi::New, ACTOR_API | IMAGE_ACTOR_API },
{"Layer", ActorWrapper::LAYER_ACTOR, LayerApi::New, ACTOR_API | LAYER_API },
{"CameraActor",ActorWrapper::CAMERA_ACTOR, CameraActorApi::New, ACTOR_API | CAMERA_ACTOR_API },
- {"TextLabel", ActorWrapper::TEXT_LABEL, TextLabelApi::New, ACTOR_API },
-
};
const unsigned int ActorApiLookupCount = sizeof(ActorApiLookup)/sizeof(ActorApiLookup[0]);
// if we don't currently support the actor type, then use type registry to create it
if( actorType == ActorWrapper::UNKNOWN_ACTOR )
{
- Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( typeName );
- if( typeInfo ) // handle, check if it has a value
- {
- Dali::BaseHandle handle = typeInfo.CreateInstance();
- if( handle )
- {
- actor = Actor::DownCast( handle );
- }
- }
- else
- {
- DALI_SCRIPT_EXCEPTION(args.GetIsolate(),"Unknown actor type");
+ DALI_SCRIPT_EXCEPTION( args.GetIsolate(), "Unknown actor type" );
return Actor();
- }
}
else
{
args.GetReturnValue().Set( localObject );
}
+void ActorWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ if( !args.IsConstructCall() )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
+ return;
+ }
+
+ bool found( false );
+ std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
+
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "missing control name" );
+ return;
+ }
+ Actor control;
+ Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( controlName );
+ if( typeInfo ) // handle, check if it has a value
+ {
+ Dali::BaseHandle handle = typeInfo.CreateInstance();
+ if( handle )
+ {
+ control = Actor::DownCast( handle );
+ }
+ }
+
+ v8::Local<v8::Object> localObject = WrapActor( isolate, control, ACTOR );
+
+ args.GetReturnValue().Set( localObject );
+}
+
+
/**
* given an actor type name, e.g. ImageActor returns the type, e.g. ActorWrapper::IMAGE_ACTOR
*/
public:
/**
- * Actor type used an index
+ * Actor type used an index.
+ * These enums are used to index the ActorApiLookup table in actor-wrapper.cpp.
+ * Any changes made must be reflected in the ActorApiLookup otherwise it may segfault when creating an actor
*/
enum ActorType
{
UNKNOWN_ACTOR = -1,
- ACTOR = 0,
- IMAGE_ACTOR =1,
- MESH_ACTOR =2,
- LAYER_ACTOR =3,
- CAMERA_ACTOR =4,
- TEXT_LABEL =5
+ ACTOR = 0,
+ IMAGE_ACTOR = 1,
+ LAYER_ACTOR = 2,
+ CAMERA_ACTOR = 3
};
/**
static void NewActor( const v8::FunctionCallbackInfo< v8::Value >& args);
/**
+ * @brief Creates a new Control wrapped inside a Javascript Object.
+ * @note: the control type is passed as a parameter e.g. 'TextField'
+ * @param[in] args v8 function call arguments interpreted
+ */
+ static void NewControl( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+ /**
* @brief Wraps an actor of a given type
*/
static v8::Handle<v8::Object> WrapActor(v8::Isolate* isolate, Dali::Actor actor,ActorType actorType);
// The Actor ObjectTemplates.
static v8::Persistent<v8::ObjectTemplate> mActorTemplate;
static v8::Persistent<v8::ObjectTemplate> mImageActorTemplate;
- static v8::Persistent<v8::ObjectTemplate> mMeshActorTemplate;
static v8::Persistent<v8::ObjectTemplate> mCameraActorTemplate;
static v8::Persistent<v8::ObjectTemplate> mLayerActorTemplate;
- static v8::Persistent<v8::ObjectTemplate> mTextLabelTemplate;
/**
* @return the wrapped actor
{ "MeshActor", ActorWrapper::NewActor },
{ "CameraActor", ActorWrapper::NewActor },
{ "Layer", ActorWrapper::NewActor },
- { "TextView", ActorWrapper::NewActor },
+ { "Control", ActorWrapper::NewControl },
{ "ResourceImage", ImageWrapper::NewImage },
{ "BufferImage", ImageWrapper::NewImage },
{ "NinePatchImage", ImageWrapper::NewImage },
bool DaliWrapper::mInstanceCreated = false;
DaliWrapper* DaliWrapper::mWrapper = NULL;
-DaliWrapper::DaliWrapper()
-:mIsolate( NULL )
+DaliWrapper::DaliWrapper( RunMode runMode, v8::Isolate* isolate )
+:mIsolate( isolate ),
+ mRunMode(runMode)
{
}
DaliWrapper& DaliWrapper::Get()
{
- if(!mInstanceCreated)
+ if( !mInstanceCreated )
{
- mWrapper = new DaliWrapper();
+ mWrapper = new DaliWrapper( RUNNING_STANDALONE, NULL );
+
mInstanceCreated = true;
- if(mWrapper)
- {
- mWrapper->Initialize();
- }
- }
+ mWrapper->InitializeStandAlone();
+ }
return *mWrapper;
}
+v8::Local<v8::Object> DaliWrapper::CreateWrapperForNodeJS( v8::Isolate* isolate )
+{
+ v8::EscapableHandleScope handleScope( isolate);
+
+ mInstanceCreated = true;
+
+ mWrapper = new DaliWrapper( RUNNING_IN_NODE_JS, isolate );
+
+ v8::Local<v8::Object> dali = mWrapper->CreateDaliObject();
+
+ // As we running inside node, we already have an isolate and context
+ return handleScope.Escape( dali );
+}
+
+v8::Local<v8::Object> DaliWrapper::CreateDaliObject()
+{
+ v8::EscapableHandleScope handleScope( mIsolate );
+
+ // Create dali object used for creating objects, and accessing constant values
+ // e.g. var x = new dali.Actor(), or var col = dali.COLOR_RED;
+
+ v8::Local<v8::ObjectTemplate> daliObjectTemplate = NewDaliObjectTemplate( mIsolate );
+
+ // add dali.staqe
+ v8::Local<v8::Object> stageObject = StageWrapper::WrapStage( mIsolate, Stage::GetCurrent() );
+ daliObjectTemplate->Set( v8::String::NewFromUtf8( mIsolate, "stage") , stageObject );
+
+ v8::Local<v8::Object> keyboardObject = KeyboardFocusManagerWrapper::WrapKeyboardFocusManager( mIsolate,Toolkit::KeyboardFocusManager::Get() );
+ daliObjectTemplate->Set( v8::String::NewFromUtf8( mIsolate, "keyboardFocusManager") , keyboardObject );
+
+
+ //create an instance of the template
+ v8::Local<v8::Object> daliObject = daliObjectTemplate->NewInstance();
+
+ ConstantsWrapper::AddDaliConstants( mIsolate, daliObject);
+
+ daliObject->Set( v8::String::NewFromUtf8( mIsolate, "V8_VERSION") ,v8::String::NewFromUtf8( mIsolate, v8::V8::GetVersion() ));
+
+ return handleScope.Escape( daliObject );
+}
+
+
void DaliWrapper::SetFlagsFromString(const std::string &flags)
{
v8::V8::SetFlagsFromString(flags.c_str(), flags.size());
void DaliWrapper::Shutdown()
{
+ // if we're running inside node then we don't have ownership of the context
+ if( mRunMode == RUNNING_IN_NODE_JS )
+ {
+ return;
+ }
+
DALI_LOG_WARNING("Destroying V8 DALi context\n");
if( !mContext.IsEmpty())
return mGarbageCollector;
}
-void DaliWrapper::CreateContext( )
+void DaliWrapper::ApplyGlobalObjectsToContext( v8::Local<v8::Context> context )
{
v8::HandleScope handleScope( mIsolate );
- // Create a global JavaScript object so we can set built-in global functions, like Log.
- v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New( mIsolate );
+ // Add global objects ( functions/ values ) e.g. log function
+ // create a console.log and console.error functions
+ v8::Local<v8::ObjectTemplate> consoleObjectTemplate = v8::ObjectTemplate::New( mIsolate );
+ consoleObjectTemplate->Set( v8::String::NewFromUtf8( mIsolate, "log"), v8::FunctionTemplate::New( mIsolate, V8Utils::Log));
+ consoleObjectTemplate->Set( v8::String::NewFromUtf8( mIsolate, "error"), v8::FunctionTemplate::New( mIsolate, V8Utils::LogError));
- // Add global objects ( functions/ values ) e.g. log function and V8_VERSION
- global->Set( v8::String::NewFromUtf8( mIsolate, "log"), v8::FunctionTemplate::New( mIsolate, V8Utils::Log) );
- global->Set( v8::String::NewFromUtf8( mIsolate, "logError"), v8::FunctionTemplate::New( mIsolate, V8Utils::LogError) );
- global->Set( v8::String::NewFromUtf8( mIsolate, "require"), v8::FunctionTemplate::New( mIsolate, DaliWrapper::Require));
- global->Set( v8::String::NewFromUtf8( mIsolate, "V8_VERSION") ,v8::String::NewFromUtf8( mIsolate, v8::V8::GetVersion() ));
+ context->Global()->Set( v8::String::NewFromUtf8( mIsolate, "console"), consoleObjectTemplate->NewInstance() );
- // add the dali object to it, assume it won't be garbage collected until global is deleted
- global->Set(v8::String::NewFromUtf8( mIsolate, DALI_API_NAME) , NewDaliObjectTemplate( mIsolate ));
+ // add require functionality
+ context->Global()->Set( v8::String::NewFromUtf8( mIsolate, "require"), v8::FunctionTemplate::New( mIsolate, DaliWrapper::Require)->GetFunction());
+ // Create the Dali object
+ // @todo consider forcing developers to perform require('dali') if we want to avoid polluting the global namespace
+ v8::Local<v8::Object> daliObject = CreateDaliObject();
- // create a new context.
- // Isolate = isolated copy of the V8 including a heap manager, a garbage collector
- // Only 1 thread can access a single Isolate at a given time. However, multiple Isolates can be run in parallel.
- // Context = multiple contexts can exist in a given Isolate, and share data between contexts
- v8::Handle<v8::Context> context = v8::Context::New( mIsolate, NULL, global);
+ // allow developers to require('dali'); // this is to maintain compatibility with node.js where dali is not part of the global namespace
+ mModuleLoader.StorePreBuiltModule( mIsolate, daliObject, DALI_API_NAME );
- mGlobalObjectTemplate.Reset( mIsolate, global);
+ context->Global()->Set( v8::String::NewFromUtf8( mIsolate, DALI_API_NAME),daliObject );
- mContext.Reset( mIsolate, context);
}
-void DaliWrapper::Initialize()
+void DaliWrapper::InitializeStandAlone()
{
if( !mIsolate )
{
// default isolate removed from V8 version 3.27.1 and beyond.
mIsolate = v8::Isolate::New();
+
mIsolate->Enter();
v8::V8::SetFatalErrorHandler( FatalErrorCallback );
-
}
+
// if context is null, create it and add dali object to the global object.
if( mContext.IsEmpty())
{
v8::HandleScope handleScope( mIsolate );
- CreateContext();
- v8::Local<v8::Context> context = v8::Local<v8::Context>::New(mIsolate, mContext);
-
- context->Enter();
- // Add the dali global object. Used for creating objects, and accessing constant values
- // e.g. var x = new dali.ImageActor(), or var col = dali.COLOR_RED;
+ // create a new context.
+ // Isolate = isolated copy of the V8 including a heap manager, a garbage collector
+ // Only 1 thread can access a single Isolate at a given time. However, multiple Isolates can be run in parallel.
+ // Context = multiple contexts can exist in a given Isolate, and share data between contexts
+ v8::Local<v8::Context> context = v8::Context::New( mIsolate );
- v8::Local<v8::Object> daliObject = v8::Local<v8::Object>::Cast( context->Global()->Get( v8::String::NewFromUtf8( mIsolate, DALI_API_NAME)));
-
- v8::Local<v8::Object> stageObject = StageWrapper::WrapStage( mIsolate, Stage::GetCurrent() );
- daliObject->Set( v8::String::NewFromUtf8( mIsolate, "stage") , stageObject );
-
- // keyboard focus manager is a singleton
- v8::Local<v8::Object> keyboardObject = KeyboardFocusManagerWrapper::WrapKeyboardFocusManager( mIsolate,Toolkit::KeyboardFocusManager::Get() );
- daliObject->Set( v8::String::NewFromUtf8( mIsolate, "keyboardFocusManager") , keyboardObject );
+ context->Enter();
- ConstantsWrapper::AddDaliConstants( mIsolate, daliObject);
+ // Apply global objects like dali and console to the context
+ ApplyGlobalObjectsToContext(context);
+ mContext.Reset( mIsolate, context);
}
+
DALI_LOG_INFO( gLogExecuteFilter, Debug::Verbose, "V8 Library %s loaded \n", v8::V8::GetVersion() );
}
+
v8::Handle<v8::ObjectTemplate> DaliWrapper::NewDaliObjectTemplate( v8::Isolate* isolate )
{
v8::EscapableHandleScope handleScope( isolate );
objTemplate->Set( v8::String::NewFromUtf8( isolate, "BUILD"),
v8::String::NewFromUtf8( isolate, "Dali binary built on:" __DATE__ ", at " __TIME__));
-
+#ifdef DALI_DATA_READ_ONLY_DIR
// add the data data directory,
objTemplate->Set( v8::String::NewFromUtf8( isolate, "DALI_DATA_DIRECTORY"),
- v8::String::NewFromUtf8( isolate, DALI_DATA_READ_ONLY_DIR));
-
+ v8::String::NewFromUtf8( isolate, DALI_DATA_READ_ONLY_DIR));
+#endif
// add our constructor functions
ObjectTemplateHelper::InstallFunctions( isolate,
objTemplate,
void DaliWrapper::Require(const v8::FunctionCallbackInfo< v8::Value >& args)
{
DaliWrapper& wrapper( DaliWrapper::Get() );
- wrapper.mModuleLoader.Require( args, wrapper.mGlobalObjectTemplate );
+ wrapper.mModuleLoader.Require( args );
}
-
-
} // namespace V8Plugin
} // namespace Dali
// INTERNAL INCLUDES
#include <garbage-collector/garbage-collector.h>
+
#include <module-loader/module-loader.h>
namespace Dali
*/
class DALI_INTERNAL DaliWrapper
{
+
public:
/**
- * Constructor
+ * @brief whether the wrapper is running in standalone using V8,
+ * or inside Node.JS using V8
*/
- DaliWrapper();
+ enum RunMode
+ {
+ RUNNING_STANDALONE,
+ RUNNING_IN_NODE_JS
+ };
+
+ /**
+ * @brief Constructor
+ * @param[in] runMode whether the wrapper is running standalone or inside Node.JS
+ * @param[in] isolate v8 isolate ( can be null if running standalone )
+ */
+ DaliWrapper( RunMode runMode, v8::Isolate* isolate );
/**
* non virtual destructor, not intended as a base class
static DaliWrapper& Get();
/**
+ * Intialize DaliWrapper for running inside NodeJS
+ */
+ static v8::Local<v8::Object> CreateWrapperForNodeJS( v8::Isolate* isolate);
+
+
+ /**
* Set V8 engine configuration flags
*
* @param[in] flags Configruation flags (See v8 documentation)
private:
/**
- * Create V8 context
+ * @brief Apply global objects like console.log and require() to the context
*/
- void CreateContext();
+ void ApplyGlobalObjectsToContext( v8::Local<v8::Context> context );
/**
- * Initialize DaliWrapper
+ * @brief Initialize DaliWrapper for running standalone
+ * Creates a new isolate
+ *
*/
- void Initialize();
+ void InitializeStandAlone();
+
+ /**
+ * @brief create dali namespace/object
+ */
+ v8::Local<v8::Object> CreateDaliObject();
/**
* Create Dali ObjectTemplate
GarbageCollector mGarbageCollector; ///< DALi garbage collector
ModuleLoader mModuleLoader; ///< Module loader
v8::Persistent<v8::Context> mContext; ///< A sandboxed execution context with its own set of built-in objects and functions.
- v8::Persistent<v8::ObjectTemplate> mGlobalObjectTemplate; ///< Global object template for storing things like dali global object
v8::Isolate* mIsolate; ///< represents an isolated instance of the V8 engine.
-
+ RunMode mRunMode;
};
ModuleLoader::ModuleLoader()
{
-
}
ModuleLoader::~ModuleLoader()
* @for ModuleLoader
*
*/
-void ModuleLoader::Require(const v8::FunctionCallbackInfo< v8::Value >& args,
-
- v8::Persistent<v8::ObjectTemplate>& globalObjectTemplate )
+void ModuleLoader::Require(const v8::FunctionCallbackInfo< v8::Value >& args )
{
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope handleScope( isolate );
args.GetReturnValue().Set( moduleExports );
}
+
+void ModuleLoader::StorePreBuiltModule( v8::Isolate* isolate, v8::Local<v8::Object>& exportObject, const std::string& name )
+{
+ StoreModule( "", name, name, isolate, exportObject );
+}
+
void ModuleLoader::StoreScriptInfo( const std::string& sourceFileName )
{
V8Utils::GetFileDirectory( sourceFileName, mCurrentScriptPath);
public:
/**
- * Constructor
+ * @brief Constructor
+ * @param[in] isolate v8 isolate
+ * @param[in] daliObject dali exports object, used when developer does require('dali');
*/
ModuleLoader();
/**
- * non virtual destructor, not intended as a base class
+ * @brief non virtual destructor, not intended as a base class
*/
~ModuleLoader();
/**
- * Execute a script from a file
+ * @brief Execute a script from a file
+ * @param[in] isolate v8 isolate
* @param[in] fileName file name
* @return true on success, false on failure
*
/**
- * Execute a script
+ * @brief Execute a script
+ * @param[in] isolate v8 isolate
* @param[in] sourceCode source code to run
* @param[in] sourceFileName source file name
* @return true on success, false on failure
/**
- * Implements JavaScript Require functionality
+ * @brief Implements JavaScript Require functionality
+ * @param[in] args arguments passed to require. The return value is set using args.GetReturnValue().Set(
*/
- void Require(const v8::FunctionCallbackInfo< v8::Value >& args, v8::Persistent<v8::ObjectTemplate>& globalObjectTemplate );
+ void Require( const v8::FunctionCallbackInfo< v8::Value >& args );
+
+ /**
+ * @brief
+ * Stores a pre compiled object as a module.
+ * Currently used for storing the Dali object, so the developer can
+ * perform var dali = require('dali');
+ * @param[in] isolate v8 isolate
+ * @param[in] exportObject export object
+ * @param[in] name module name, used for the require('name') lookup
+ */
+ void StorePreBuiltModule( v8::Isolate* isolate, v8::Local<v8::Object>& exportObject, const std::string& name );
private:
const std::string& sourceFileName );
/**
- * Store information about the current script
+ * @brief Store information about the current script
* @param[in] sourceFileName source file name
*/
void StoreScriptInfo( const std::string& sourceFileName );
/**
- * Store module information
+ * @brief Store module information
* @param[in] sourceFileName source file name
* @return module object
*/
v8::Local<v8::Object>& moduleExportsObject );
/**
- * Find a module
+ * @brief Find a module
* @param[in] moduleName module name
* @return module
*/
std::cout << " ";
}
v8::String::Utf8Value utf8_value( args[i] );
- std::cout << *utf8_value;
+ std::cout << *utf8_value << "\n";
}
}
}
v8::String::Utf8Value utf8_value( args[i] );
output += *utf8_value;
+ output +="\n";
}
DALI_LOG_ERROR_NOFN( "JavaScript: %s",output.c_str() );
}